This document applies to Fedora 29. But, all should work on CentOS/REL 7.
Before you can work with all the selinux tools, you must install the following packages first:
dnf -y install python3-policycoreutils policycoreutils-python-utils policycoreutils setroubleshoot-server setools-console libselinux-utils coreutils
semanage fcontext -l
Note: | seinfo is part of setools-console rpm package. |
seinfo -t Types: 4840 NetworkManager_etc_rw_t NetworkManager_etc_t NetworkManager_exec_t NetworkManager_initrc_exec_t NetworkManager_log_t ...
Note: | You should grep for a context, or pipe into less ! |
seinfo -u Users: 8 guest_u root staff_u sysadm_u system_u unconfined_u user_u xguest_u
seinfo -r Roles: 14 auditadm_r dbadm_r guest_r logadm_r nx_server_r object_r secadm_r staff_r sysadm_r system_r unconfined_r user_r webadm_r xguest_r
The semanage
command has tree switches:
-a
: add the context-m
: modify the context-d
: deletes the context
Next, a few examples for managing context using semanage
command:
semanage fcontext -a -t httpd_sys_rw_content_t -f f 'test'
semanage fcontext -a -t httpd_sys_rw_content_t -f d 'test'
semanage fcontext -a -t httpd_sys_rw_content_t -f f 'test(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t -f d 'test(/.*)?'
Here, I show some examples for the regex:
'test/(one|two)(/.)?'
: This would match test/one/
and test/two/*
, but, not more recursive/opt/zendto/'(/.)?'
: This matches everything in /opt/zendto/
directory, but, not more recursiveTo recuresively apply the context permanently, use this command:
restorecon -R -v test
Note: | Usually it’s not a bad idea to use the -v switch, this shows, what it changes. |
-R
option:restorecon test
Boleans are general values, they are valid for the whole system.
getsebool -a
Note: | Use grep or pipe into less ! |
setsebool -P httpd_can_network_connect true
All changes, which where not saved, using restorcon
command, will be lost, when you run a relabeling!
restorecon -R /www
fixfiles relabel
fixfiles -R <packagename> restore
If you have to relable the system, just create /.autorelabel file and reboot the server. |
touch /.autorelabel
Note: | Before reboot, make sure selinux is in permissive mode! System does not always reboot after enforcing SELINUX. |
touch /.autorelabel grep '^SELINUX' /etc/sysconfig/selinux SELINUX=permissive SELINUXTYPE=targeted reboot
linux16 ... rd.break enforcing=0
Note: | rd.break asks for a break at an early stage of the boot process. enforcing=0 puts the system into SELinux Permissive mode. Don’t confuse with selinux=0 that completely disables SELinux. |
cat /var/log/audit/audit.log | audit2why
httpd
service:grep httpd /var/log/audit/audit.log |audit2why
semanage
:cat /var/log/audit/audit.log | audit2allow
sealert
command to get a report of all problems related to selinux
. But, you have to install first following package (on CentOS, RHEL or Fedora distributions):dnf -y install setroubleshoot-server
sealert -a /var/log/audit/audit.log
100% done found 1 alerts in /var/log/audit/audit.log -------------------------------------------------------------------------------- SELinux is preventing logrotate from map access on the file /etc/logrotate.d/mariadb. ***** Plugin restorecon (92.2 confidence) suggests ************************ If you want to fix the label. /etc/logrotate.d/mariadb default label should be etc_t. Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly. Do # /sbin/restorecon -v /etc/logrotate.d/mariadb ***** Plugin catchall_boolean (7.83 confidence) suggests ****************** If you want to allow domain to can mmap files Then you must tell SELinux about this by enabling the 'domain_can_mmap_files' boolean. Do setsebool -P domain_can_mmap_files 1 ***** Plugin catchall (1.41 confidence) suggests ************************** If you believe that logrotate should be allowed map access on the mariadb file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # ausearch -c 'logrotate' --raw | audit2allow -M my-logrotate # semodule -X 300 -i my-logrotate.pp Additional Information: Source Context system_u:system_r:logrotate_t:s0-s0:c0.c1023 Target Context unconfined_u:object_r:mysqld_etc_t:s0 Target Objects /etc/logrotate.d/mariadb [ file ] Source logrotate Source Path logrotate Port <Unknown> Host <Unknown> Source RPM Packages Target RPM Packages mariadb-server-10.3.11-1.fc29.x86_64 Policy RPM selinux-policy-3.14.2-47.fc29.noarch Selinux Enabled True Policy Type targeted Enforcing Mode Enforcing Host Name danweb2 Platform Linux danweb2 4.20.3-200.fc29.x86_64 #1 SMP Thu Jan 17 15:19:35 UTC 2019 x86_64 x86_64 Alert Count 1 First Seen 2019-02-08 03:19:01 CET Last Seen 2019-02-08 03:19:01 CET Local ID 17b1c2f9-04fa-43c8-b799-9221390e3fa6 Raw Audit Messages type=AVC msg=audit(1549592341.516:621241): avc: denied { map } for pid=19834 comm="logrotate" path="/etc/logrotate.d/mariadb" dev="dm-0" ino=2494230 scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:mysqld_etc_t:s0 tclass=file permissive=0 Hash: logrotate,logrotate_t,mysqld_etc_t,file,map
yum install setools-console setroubleshoot-server setroubleshoot-plugins policycoreutils-python-utils
selinux
:getenforce
selinux
does not allow proxy connections to other hosts, you can enable this:setsebool -P httpd_can_network_connect true
getsebol -a
command:getsebool -a |grep http httpd_anon_write --> off httpd_builtin_scripting --> on httpd_can_check_spam --> off httpd_can_connect_ftp --> off httpd_can_connect_icinga2_api --> on httpd_can_connect_ldap --> off httpd_can_connect_mythtv --> off httpd_can_connect_zabbix --> off httpd_can_manage_icingaweb2_config --> on httpd_can_network_connect --> off httpd_can_network_connect_cobbler --> off httpd_can_network_connect_db --> off httpd_can_network_memcache --> off httpd_can_network_relay --> off httpd_can_sendmail --> off httpd_can_write_icinga2_command --> on httpd_dbus_avahi --> off httpd_dbus_sssd --> off httpd_dontaudit_search_dirs --> off httpd_enable_cgi --> on httpd_enable_ftp_server --> off httpd_enable_homedirs --> off httpd_execmem --> off httpd_graceful_shutdown --> off httpd_manage_ipa --> off httpd_mod_auth_ntlm_winbind --> off httpd_mod_auth_pam --> off httpd_read_user_content --> off httpd_run_ipa --> off httpd_run_preupgrade --> off httpd_run_stickshift --> off httpd_serve_cobbler_files --> off httpd_setrlimit --> off httpd_ssi_exec --> off httpd_sys_script_anon_write --> off httpd_tmp_exec --> off httpd_tty_comm --> off httpd_unified --> off httpd_use_cifs --> off httpd_use_fusefs --> off httpd_use_gpg --> off httpd_use_nfs --> off httpd_use_openstack --> off httpd_use_sasl --> off httpd_verify_dns --> off mysql_connect_http --> off named_tcp_bind_http_port --> off prosody_bind_http_port --> off
ldap
server or a mysql
database from a web application, you should set this boleans to true:setsebool -P httpd_can_network_connect_db true setsebool -P httpd_can_connect_ldap true
For example the Bolt CMS requires to write files in the in public
, cache
and config
folders. But, selinux
does not allow this per default.
chcon -t httpd_sys_rw_content_t /var/www/ds/app/cache -R
base="/var/www" d=ds # make sure the httpd sys context is setup properly: semanage fcontext -a -t httpd_sys_content_t ${base}/${d}'(/.*)?' restorecon -R ${base}/$d # next folder and file have to be read/write: semanage fcontext -a -t httpd_sys_rw_content_t ${base}/$d/app/cache'(/.*)?' semanage fcontext -a -t httpd_sys_rw_content_t ${base}/$d/app/config'(/.*)?' semanage fcontext -a -t httpd_sys_rw_content_t ${base}/$d/public/files'(/.*)?' semanage fcontext -a -t httpd_sys_rw_content_t ${base}/$d/public/extensions'(/.*)?' semanage fcontext -a -t httpd_sys_rw_content_t ${base}/$d/extensions'(/.*)?' # make all permanent (recuresive) restorecon -R ${base}/$d/app/cache restorecon -R ${base}/$d/app/config restorecon -R ${base}/$d/public/files restorecon -R ${base}/$d/public/extensions restorecon -R ${base}/$d/extensions
selinux
attributes:sudo chcon -R --reference=/usr/share/nginx/html /www
apache
default webroot directory:sudo chcon -R --reference=/var/www/html /www
Note: | If you want to have those changes to default back, you must execute restorecon -R /<directory> ! |
restorecon -R /www
If the icinga service does not start after configuring API, you should check the following:
semanage port -l | grep 5665
semanage port -a -t icinga2_port_t -p tcp 5665
semanage port -l | grep 5665
Not yet done …
If you have an application which has not a standart port definition, you can also define a port for a service.
semanage port -a -t httpd_port_t -p tcp 8888
For a password change, next procedure is probably the easiest.
E
to edit the default boot optionlinux16
is listed first, following rd.break enforcing=0
/sysroot
, but writable: mount –o remount,rw /sysroot
/sysroot
: chroot /sysroot
/.autorelabel
in /sysroot
or reboot and add autorelabel=1
in grubSELINUX=0
kernel parameter. This will cause the kernel to not load any of the SELinux infrastructure. The init scripts will notice that you booted with SELINUX=0
and will touch /.autorelabel themselves. This will cause the machine to automatically relabel the next time you boot with SELINUX
enabled. We do this because anytime you are booted with SELNUX=0
files will not get a label. So the next time the system boots the SELinux would report these files as file_t
and almost no domains can interfact with a file_t
(Unlabeled file). Files like /etc/resolv.conf
get recreated at boot time and probably would get this label and the next time SELinux booted, all heck would break loose./lib
directories are labeled lib_t. strict policy only allows confined apps to execute shlib_t
. In targeted policy shlib_t and lib_t are aliases. (Having these files labeled differently is of little security importance and leads to labeling problems in my opinion). So every file in /lib
directories gets the label lib_t
. When you boot a machine that is labeled for targeted with strict policy the confined apps try to execute lib_t labeled shared libraries so and they are denied. /sbin/init
tries this and blows up. So booting in permissive mode allows the system to relabel the shared libraries as shlib_t
and then the next boot can be done in enforcing.
Sometimes not all rules apply to a application. Then, you need to create your own selinux
module. In this example the rrdtool
binary:
/var/log/audit/audti.log
:p=rrdtool; grep 'comm="'$p /var/log/audit/audit.log | audit2allow -l module local_rrdtool 1.0; require { type httpd_t; type nagios_var_lib_t; class file map; } #============= httpd_t ============== # src="httpd_t" tgt="nagios_var_lib_t" class="file", perms="map" # comm="rrdtool" exe="" path="" #!!!! This avc can be allowed using the boolean 'domain_can_mmap_files' allow httpd_t nagios_var_lib_t:file map;
p=rrdtool; grep 'comm="'$p /var/log/audit/audit.log | audit2allow -l -v -m local_$p > local_$p.te
The result is now local_$p.te
file.
checkmodule -M -m -o local_$p.mod local_$p.te
This creates the local_$p.mod
file.
semodule_package -o local_$p.pp -m local_$p.mod
This results in local_$p.pp
selinux module
/usr/share/selinux/targeted
directory:semodule -v -i local_$p.pp Attempting to install module 'local_rrdtool.pp': Ok: return value of 0. Committing changes: Ok: transaction number 21. cp local_$p.pp /usr/share/selinux/targeted/
It's a good idea to use a prefix for the module name (in my case: local_
)!
If you want to create a module for more than one binary (because they are part of an application), just use audit2allow -a
to create the module configuration.
selinux
:sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: actual (secure) Max kernel policy version: 31
selinux
modules (there are many, use grep!):semodule -l