selinux

This is an old revision of the document!


SELinux

  • List of all selinux contexts (detailed):
    semanage fcontext -l
Note:seinfo is part of setools-console rpm package.
  • List only the contexts:
    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!
  • List all selinux users:
    seinfo -u
     
    Users: 8
       guest_u
       root
       staff_u
       sysadm_u
       system_u
       unconfined_u
       user_u
       xguest_u
  • List all selinux user roles:
    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:

  • Change a filecontext for one file:
    semanage fcontext -a -t httpd_sys_rw_content_t -f f 'test'
  • Change a filecontext for one directory:
    semanage fcontext -a -t httpd_sys_rw_content_t -f d 'test'
  • Change a filecontext for files recursivly:
    semanage fcontext -a -t httpd_sys_rw_content_t -f f 'test(/.*)?'
  • Change a filecontext for one directory:
    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 recursive

To recuresively apply the context permanently, use this command:

  • Make it recuresive permanent:
    restorecon -R -v test
Note:Usually it’s not a bad idea to use the -v switch, this shows, what it changes.
  • If you want to apply the context permanently only to the given file/folder, you can do it without -R option:
    restorecon test

Boleans are general values, they are valid for the whole system.

  • List of all selinux boleans:
    getsebool -a
Note:Use grep or pipe into less!
  • Allow the webserver to connect to other web servers:
    setsebool -P httpd_can_network_connect true

All changes, which where not saved, using restorcon command, will be lost, when you run a relabeling!

  • Make sure the changes you made survive a relabeling:
    restorecon -R /www
  • It is possible to relabel a file system using the fixfiles command, or to relabel based on the RPM database. Use the following command to relabel a file system only using the fixfiles command:
    fixfiles relabel
  • Use the following command to relabel a file system based on the RPM database:
    fixfiles -R <packagename> restore
If you have to relable the system, just create /.autorelabel file and reboot the server.
  • Prepare auto relabeling during boot:
    touch /.autorelabel
Note:Before reboot, make sure selinux is in permissive mode! System does not always reboot after enforcing SELINUX.
  • Make sure the relabeling is set to permissive to allow the relabeling during boot:
    touch /.autorelabel
    grep '^SELINUX' /etc/sysconfig/selinux
    SELINUX=permissive
    SELINUXTYPE=targeted
    reboot
  • If the server fails to boot, put in the end of the follwing line in grub2 prompt:
    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.
  • Audit the audit log (in general):
    cat /var/log/audit/audit.log | audit2why
  • Unordered List Itemor more speicific for example for the httpd service:
    grep httpd /var/log/audit/audit.log |audit2why
  • Label the changes you made with semanage:
    cat /var/log/audit/audit.log | audit2allow
  • You can also use the 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
  • This gives, as an example, following result:
    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
  • Unordered List ItemYou need to install the following package:
    yum install setools-console setroubleshoot-server setroubleshoot-plugins policycoreutils-python-utils
  • Unordered List ItemCheck, what state has selinux:
    getenforce
  • Per default, selinux does not allow proxy connections to other hosts, you can enable this:
    setsebool -P httpd_can_network_connect true
  • To get a list of all boleans, you can use the 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
  • For example, if you need to connect an 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.

  • Copy the attributes from apache default webroot directory:
    chcon -t httpd_sys_rw_content_t /var/www/ds/app/cache -R
  • For the bolt setup, you can replace the base directory variable:
    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
  • It’s also possible to a reference copy of the selinux attributes:
    sudo chcon -R --reference=/usr/share/nginx/html /www
  • Copy the attributes from 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>!
  • Make labeling changes back to default:
    restorecon -R /www

If the icinga service does not start after configuring API, you should check the following:

  • Check, if port 5665 is allowed:
    semanage port -l | grep 5665
  • If empty, you have to configure it:
    semanage port -a -t icinga2_port_t -p tcp 5665
  • Check, if port 5665 is allowed:
    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.

  • Example for configuring port 8888 for httpd service:
    semanage port -a -t httpd_port_t -p tcp 8888

For a password change, next procedure is probably the easiest.

  1. Interrupt grub startup and type E to edit the default boot option
  2. Add at the line where linux16 is listed first, following rd.break enforcing=0
  3. Remount /sysroot, but writable: mount –o remount,rw /sysroot
  4. Do a chroot to /sysroot: chroot /sysroot
  5. Do your changes
  6. You have to relabel the filesystems, just touch /.autorelabel in /sysroot or reboot and add autorelabel=1 in grub
  • selinux=0 (Bad idea)
    If you want to Disable SELinux entirely. You can boot the system with the SELINUX=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.
  • enforcing=0
    Setting this parameter will cause the machine to boot in permissive mode. If your machine will not boot in enforcing mode, this can allow you to boot it and figure out what is wrong. Sometimes you file system can get so messed up that this parameter is your only option. The nice thing about this option, the system continues to create the labels correctly. The AVC messages that are created via this command can be different then in enforcing mode. There are two differences in enforcing mode, every access denial is reported, in permissive only the first denial is reported. However in Enforcing mode you might get a denial on reading a directory and the app will stop. In permissive mode you would get the same avc message but then you would get an avc for each denial when the app continues reading files in the directory.
  • autorelabel=1
    This parameter will force the system to relabel. It does the same thing as “touch /.autorelabe; reboot”. Sometimes, if the machines labeling is really bad, you will need to boot in permissive mode in order for the autorelabel to succeed. An example of this is switching from strict to targeted policy. In strict policy shared libraries are labeled as shlib_t while ordinary files in /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 rrdtool:

  1. Get information from /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;
  2. Create now the module configuration file *.te:
    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.

  3. Check now the syntax of the config file:
    checkmodule -M -m -o local_$p.mod local_$p.te

    This creates the local_$p.mod file.

  4. Create now the module for selinux:
    semodule_package -o local_$p.pp -m local_$p.mod

    This results in local_$p.pp selinux module

  5. Activate the module and copy it to /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/
  • selinux.1552639750.txt.gz
  • Last modified: 2019/03/15 09:49
  • by dani