Bookmark this page

Lab: Mitigating Risk with SELinux

Performance Checklist

In this lab, you will configure confined users and fix some SELinux denials.

Outcomes

You should be able to:

  • Ensure SELinux is in enforcing mode.

  • Configure confined users and administrators.

  • Audit the SELinux policy to explain the context of a process.

  • Resolve SELinux AVC denials.

Confirm that the workstation and serverd machines are started.

Log in to workstation as student using student as the password. On workstation, run lab selinux-review setup to verify that the environment is ready. This script also prepares serverd for the exercise.

[student@workstation ~]$ lab selinux-review setup
  1. On serverd, change the default SELinux mode to enforcing. The change must persist across reboots.

    1. Log in to serverd as student. No password is required.

      [student@workstation ~]$ ssh student@serverd
      [student@serverd ~]$ 
    2. Use the sudo -i command to switch identity to the root user. Use student as the password.

      [student@serverd ~]$ sudo -i
      [sudo] password for student: student
      [root@serverd ~]# 
    3. Get the current SELinux mode.

      [root@serverd ~]# getenforce
      Permissive
    4. Edit the /etc/selinux/config file and set the SELINUX variable to enforcing.

      [root@serverd ~]# vim /etc/selinux/config
      ...output omitted...
      SELINUX=enforcing
      ...output omitted...
    5. Use the setenforce command to change the current mode to enforcing. Verify your work with the getenforce command.

      [root@serverd ~]# setenforce 1
      [root@serverd ~]# getenforce
      Enforcing

      Because the originally that server was using the enforcing mode, you do not need to reboot serverd.

  2. On serverd, try to start the httpd service. Diagnose the problem and fix the issue.

    When done, try to access the index.html page. Fix the issue.

    1. Try to start the httpd service.

      [root@serverd ~]# systemctl start httpd
      Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
    2. As instructed by the error message, run the systemctl status httpd.service command to get more detail.

      [root@serverd ~]# systemctl status httpd.service
      ● httpd.service - The Apache HTTP Server
         Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
         Active: failed (Result: exit-code) since Wed 2018-07-25 05:49:17 EDT; 3min 33s ago
           Docs: man:httpd(8)
                 man:apachectl(8)
        Process: 2846 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
        Process: 2845 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
       Main PID: 2845 (code=exited, status=1/FAILURE)
      
      Jul 25 05:49:17 serverd.lab.example.com systemd[1]: Starting The Apache HTTP Server...
      Jul 25 05:49:17 serverd.lab.example.com httpd[2845]: (13)Permission denied: AH00091: httpd: could not open error log file /etc/httpd/logs/error_log.
      Jul 25 05:49:17 serverd.lab.example.com httpd[2845]: AH00015: Unable to open logs
      ...output omitted...
    3. Collect more clues by inspecting the /etc/httpd/logs directory.

      [root@serverd ~]# ls -ld /etc/httpd/logs
      lrwxrwxrwx. 1 root root 18 Jul 25 04:28 /etc/httpd/logs -> /custom/httpd_logs

      /etc/httpd/logs is a link to a custom directory; the default is usually /var/log/httpd.

    4. Search for SELinux denials in the /var/log/audit/audit.log file.

      [root@serverd ~]# grep denied /var/log/audit/audit.log
      type=AVC msg=audit(1532512157.422:2686): avc:  denied  { write } for  pid=2845 comm="httpd" name="httpd_logs" dev="vda1" ino=13489 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

      You can also use the ausearch command.

      [root@serverd ~]# ausearch -m AVC
      \----
      time->Wed Jul 25 05:49:17 2018
      type=PROCTITLE msg=audit(1532512157.422:2686): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1532512157.422:2686): arch=c000003e syscall=2 success=no exit=-13 a0=558bf9944c00 a1=80441 a2=1b6 a3=7ffcdc7a4a10 items=0 ppid=1 pid=2845 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
      type=AVC msg=audit(1532512157.422:2686): avc:  denied  { write } for  pid=2845 comm="httpd" name="httpd_logs" dev="vda1" ino=13489 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

      The message indicates that SELinux denies the httpd process write access to the httpd_logs directory, whose inode number is 13489. This inode number is probably different on your system.

      The httpd_logs directory has the wrong SELinux context.

    5. You probably only have one directory named httpd_logs on your system, but because the SELinux message does not give you the full path, you cannot be sure. Use the find command with the -inum option to locate the directory by its inode number.

      [root@serverd ~]# find / -inum 13489
      /custom/httpd_logs

      Remember to replace the inode number in the command with the one you collected in the previous step.

    6. To find out the context type to set on the /custom/httpd_logs directory, retrieve the context type of the default log directory, /var/log/httpd.

      [root@serverd ~]# ls -Zd /var/log/httpd
      drwx------. root root system_u:object_r:httpd_log_t:s0 /var/log/httpd
    7. Use the semanage fcontext command to add the new rule for /custom/httpd_log.

      [root@serverd ~]# semanage fcontext -a -t httpd_log_t \
      > '/custom/httpd_logs(/.*)?'
      [root@serverd ~]# 
    8. Remember to restore the context of the /custom/httpd_logs directory.

      [root@serverd ~]# restorecon -Rv /custom/httpd_logs
      restorecon reset /custom/httpd_logs context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_log_t:s0
    9. Verify that you can now start the httpd service.

      [root@serverd ~]# systemctl start httpd
      [root@serverd ~]# systemctl is-active httpd
      active
    10. Use the curl command to access the index.html page.

      [root@serverd ~]# curl http://localhost/index.html
      <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
      <html><head>
      <title>403 Forbidden</title>
      </head><body>
      <h1>Forbidden</h1>
      <p>You don't have permission to access /index.html
      on this server.</p>
      </body></html>

      The command output indicates that httpd cannot access the index.html file.

    11. Verify that the index.html file exists and has the correct Linux access rights.

      [root@serverd ~]# ls -l /var/www/html/index.html
      -rw-r--r--. 1 root root 15 Jul 25 04:28 /var/www/html/index.html

      The file exists and has the correct access rights.

    12. Search for SELinux denials in the /var/log/audit/audit.log file.

      [root@serverd ~]# grep denied /var/log/audit/audit.log
      type=AVC msg=audit(1532512157.422:2686): avc:  denied  { write } for  pid=2845 comm="httpd" name="httpd_logs" dev="vda1" ino=13489 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir
      type=AVC msg=audit(1532514740.732:2735): avc:  denied  { getattr } for  pid=3778 comm="httpd" path="/var/www/html/index.html" dev="vda1" ino=484 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
      type=AVC msg=audit(1532514740.733:2736): avc:  denied  { getattr } for  pid=3778 comm="httpd" path="/var/www/html/index.html" dev="vda1" ino=484 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file

      The last message indicates that SELinux denies the httpd process access to the /var/www/html/index.html file.

    13. Review the context type of the /var/www/html/index.html file and its parent directory.

      [root@serverd ~]# ls -Z /var/www/html/index.html
      -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /var/www/html/index.html
      [root@serverd ~]# ls -Zd /var/www/html
      drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html

      index.html does not have the correct context.

    14. You do not need to add a new file context rule because /var/www/html is the default DocumentRoot directory and already has a rule. You only need to relabel index.html.

      [root@serverd ~]# restorecon -v /var/www/html/index.html
      restorecon reset /var/www/html/index.html context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
    15. Confirm that you can now access the index.html page.

      [root@serverd ~]# curl http://localhost/index.html
      Hello, Student
  3. Confine the users on serverd to prevent them from using the sudo and su commands. Further, they must not be able to run programs in /tmp or in their home directory. These restrictions do not apply to the root user.

    You can test your restrictions by logging in as student and trying the sudo -i command. You can also try to execute the runme program in /tmp and /home/student to verify your work.

    1. Change the default mapping between the Linux and the SELinux users. Map the Linux users to the user_u SELinux user.

      [root@serverd ~]# semanage login -m -s user_u -r s0 __default__
      [root@serverd ~]# 
    2. To prevent users from running programs in /tmp or their home directory, set the SELinux user_exec_content Boolean to off.

      [root@serverd ~]# setsebool -P user_exec_content off
      [root@serverd ~]# 
    3. Log out of serverd and log in again as student.

      [root@serverd ~]# logout
      [student@serverd ~]$ logout
      [student@workstation ~]$ ssh student@serverd
      [student@serverd ~]$ 
    4. Confirm that you can no longer use the sudo -i command.

      [student@serverd ~]$ sudo -i
      sudo: PERM_SUDOERS: setresuid(-1, 1, -1): Operation not permitted
      sudo: no valid sudoers sources found, quitting
      sudo: setresuid() [0, 0, 0] -> [1000, -1, -1]: Operation not permitted
      sudo: unable to initialize policy plugin
      [student@serverd ~]$ 
    5. Confirm that you cannot execute programs in /tmp or /home/student. Use the runme program for that test.

      [student@serverd ~]$ /tmp/runme
      -bash: /tmp/runme: Permission denied
      [student@serverd ~]$ ./runme
      -bash: ./runme: Permission denied
  4. Create the following system administrator account:

    • User name: operator2

    • Password: redhat

    • Supplementary group: wheel

    Map the operator2 user to a confined SELinux user to restrict su access, but make sure that they can use the sudo command. Further, operator2 must be able to log in using ssh.

    1. Log out of serverd and log in as root.

      [student@serverd ~]$ logout
      [student@workstation ~]$ ssh root@serverd
      [root@serverd ~]# 
    2. Create the operator2 account according to the requirements, and map it to the sysadm_u SELinux user.

      [root@serverd ~]# useradd -G wheel -Z sysadm_u operator2
      [root@serverd ~]# echo redhat | passwd --stdin operator2
      Changing password for user operator2.
      passwd: all authentication tokens updated successfully.
    3. Set the ssh_sysadm_login SELinux Boolean to on so that sysadm_u SELinux users can log in using SSH.

      [root@serverd ~]# setsebool -P ssh_sysadm_login on
      [root@serverd ~]# 
    4. Log out of serverd and log in as operator2.

      [root@serverd ~]# logout
      [student@workstation ~]$ ssh operator2@serverd
      [operator2@serverd ~]$ 
    5. Confirm that you can use the sudo -i command to become root. Use redhat for the password. When done, log out from serverd.

      [operator2@serverd ~]$ sudo -i
      [sudo] password for operator2: redhat
      [root@serverd ~]# logout
      [operator2@serverd ~]$ logout
      [student@workstation ~]$ 
  5. Locate the type_transition SELinux rule that explains the following behavior:

    • The ps -Z $$ command shows that student user's bash process is running under the user_t domain type.

    • The ls -Z /usr/bin/passwd command shows that the passwd binary file has the passwd_exec_t type.

    • When student runs the passwd command to change their password, the resulting process is running under the passwd_t domain type.

    After you have located the rule, store it in the /home/student/rule file on serverd. The grading script at the end of this exercise uses that file to verify your work.

    1. Replicate the scenario to confirm the described behavior.

      Log in to serverd as student. No password is required.

      [student@workstation ~]$ ssh student@serverd
      [student@serverd ~]$ 
    2. Retrieve the domain type of the bash process.

      [student@serverd ~]$ ps -Z $$
      LABEL                             PID TTY      STAT   TIME COMMAND
      user_u:user_r:user_t:s0         13192 pts/1    Ss     0:00 -bash
    3. Retrieve the context type of the /usr/bin/passwd binary file.

      [student@serverd ~]$ ls -Z /usr/bin/passwd
      -rwsr-xr-x. root root system_u:object_r:passwd_exec_t:s0 /usr/bin/passwd
    4. Run the passwd command but do not enter any password. Leave the command running; you don't want to change your password, you just want to inspect the context of the process.

      [student@serverd ~]$ passwd
      Changing password for user student.
      Changing password for student.
      (current) UNIX password:
    5. Open a new terminal on workstation and log in to serverd as root.

      [student@workstation ~]$ ssh root@serverd
      [root@serverd ~]# 
    6. Retrieve the context type of the running passwd process.

      [root@serverd ~]# ps -Z -C passwd
      LABEL                             PID TTY          TIME CMD
      user_u:user_r:passwd_t:s0       13491 pts/1    00:00:00 passwd
    7. Install the setools-console package to get the sesearch command.

      [root@serverd ~]# yum install setools-console
      ...output omitted...
      Is this ok [y/d/N]: y
      ...output omitted...
      Complete!
    8. Use the sesearch command with the following options:

      • -T - search for transition rules

      • -s user_t - the source domain is the domain of student user Bash shell.

      • -t passwd_exec_t- the target is the context of the passwd binary file

      [root@serverd ~]# sesearch -T -s user_t -t passwd_exec_t
      Found 1 semantic te rules:
         type_transition user_t passwd_exec_t : process passwd_t;

      You can also combine the sesearch command with grep.

      [root@serverd ~]# sesearch -T -s user_t | grep passwd_t
         type_transition user_t passwd_exec_t : process passwd_t;
    9. Redirect the output of one of the previous commands to /home/student/rule. When done, log out from serverd.

      [root@serverd ~]# sesearch -T -s user_t -t passwd_exec_t > /home/student/rule
      [root@serverd ~]# logout
      [student@workstation ~]$ 

      In the second terminal, cancel the passwd command and log out from serverd.

      ^C
      [student@serverd ~]$ logout
      [student@workstation ~]$ 

Evaluation

As the student user on workstation, run the lab selinux-review script with the grade argument to confirm success of this exercise. Correct any reported failures and rerun the script until successful.

[student@workstation ~]$ lab selinux-review grade

Cleanup

On workstation, run the lab selinux-review cleanup command to clean up this exercise.

[student@workstation ~]$ lab selinux-review cleanup

This concludes the lab.

Revision: rh415-7.5-813735c