Bookmark this page

Lab: Mitigating Risk with SELinux

Configure confined users and address some SELinux denials.

Outcomes

  • Ensure that 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.

As the student user on the workstation machine, use the lab command to prepare your environment for this exercise, and to ensure that all required resources are available.

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

Instructions

  1. On the serverd machine, change the default SELinux mode to enforcing. The change must persist across reboots.

    1. Log in to the serverd machine as the student user. 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 the enforcing value.

      ...output omitted...
      SELINUX=enforcing
      ...output omitted...
    5. Reboot the serverd machine to load the new configuration. Wait for the reboot to complete and verify your work with the getenforce command.

      [root@serverd ~]# reboot
      Connection to serverd closed.
      [student@workstation ~]$ ssh student@serverd
      [student@serverd ~]$ sudo -i
      [sudo] password for student: student
      [root@serverd ~]# getenforce
      Enforcing
  2. On the serverd machine, 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 -xeu httpd.service" for details.
    2. As instructed by the error message, run the systemctl status httpd.service command to get more information.

      [root@serverd ~]# systemctl status httpd.service
      × httpd.service - The Apache HTTP Server
           Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; preset: disabled)
           Active: failed (Result: exit-code) since Thu 2023-10-19 17:46:24 EDT; 34s ago
             Docs: man:httpd.service(8)
          Process: 1122 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
         Main PID: 1122 (code=exited, status=1/FAILURE)
           Status: "Reading configuration..."
              CPU: 40ms
      
      Oct 19 17:46:24 serverd systemd[1]: Starting The Apache HTTP Server...
      Oct 19 17:46:24 serverd httpd[1122]: (13)Permission denied: AH00091: httpd: could not open error log file /etc/httpd/logs/error_log.
      Oct 19 17:46:24 serverd httpd[1122]: AH00015: Unable to open logs
      Oct 19 17:46:24 serverd systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
      Oct 19 17:46:24 serverd systemd[1]: httpd.service: Failed with result 'exit-code'.
      Oct 19 17:46:24 serverd systemd[1]: Failed to start The Apache HTTP Server.
      ...output omitted...
    3. Collect more details by inspecting the /etc/httpd/logs directory.

      [root@serverd ~]# ls -ld /etc/httpd/logs
      lrwxrwxrwx. 1 root root 19 Oct 19 17:33 /etc/httpd/logs -> /custom/httpd_logs/

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

    4. Temporarily enable SELinux denial auditing and reattempt to start the httpd service.

      [root@serverd ~]# semodule -DB
      [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 -xeu httpd.service" for details.
    5. Search for SELinux denials by using the ausearch command.

      [root@serverd ~]# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
      ----
      time->Thu Oct 19 17:57:26 2023
      type=PROCTITLE msg=audit(1697752646.877:89): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697752646.877:89): arch=c000003e syscall=54 success=no exit=-1 a0=3 a1=1 a2=20 a3=7ffe8bad4734 items=0 ppid=1 pid=1171 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(1697752646.877:89): avc:  denied  { net_admin } for  pid=1171 comm="httpd" capability=12  scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capability permissive=0
      ----
      time->Thu Oct 19 17:57:26 2023
      type=PROCTITLE msg=audit(1697752646.891:90): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697752646.891:90): arch=c000003e syscall=257 success=no exit=-13 a0=ffffff9c a1=564d51b1c1f0 a2=80441 a3=1b6 items=0 ppid=1 pid=1171 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(1697752646.891:90): avc:  denied  { write } for  pid=1171 comm="httpd" name="httpd_logs" dev="vda4" ino=8582288 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir permissive=0
      ----
      ...output omitted...

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

      The httpd_logs directory has the wrong SELinux context.

    6. You probably have only 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 8582288
      /custom/httpd_logs

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

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

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

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

      [root@serverd ~]# restorecon -Rv /custom/httpd_logs
      Relabeled /custom/httpd_logs from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_log_t:s0
    10. Verify that you can now start the httpd service.

      [root@serverd ~]# systemctl start httpd
      [root@serverd ~]# systemctl is-active httpd
      active
    11. 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 this resource.</p>
      </body></html>

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

    12. 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.

    13. Search for SELinux denials by using the ausearch command.

      [root@serverd ~]# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
      ...output omitted...
      ----
      time->Thu Oct 19 18:25:46 2023
      type=PROCTITLE msg=audit(1697754346.334:116): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697754346.334:116): arch=c000003e syscall=262 success=no exit=-13 a0=ffffff9c a1=7f3f4c045d78 a2=7f3f517e18b0 a3=0 items=0 ppid=1248 pid=1251 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
      type=AVC msg=audit(1697754346.334:116): avc:  denied  { getattr } for  pid=1251 comm="httpd" path="/var/www/html/index.html" dev="vda4" ino=16857024 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
      ----
      time->Thu Oct 19 18:25:46 2023
      type=PROCTITLE msg=audit(1697754346.334:117): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697754346.334:117): arch=c000003e syscall=262 success=no exit=-13 a0=ffffff9c a1=7f3f4c045e58 a2=7f3f517e18b0 a3=100 items=0 ppid=1248 pid=1251 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
      type=AVC msg=audit(1697754346.334:117): avc:  denied  { getattr } for  pid=1251 comm="httpd" path="/var/www/html/index.html" dev="vda4" ino=16857024 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
      ----
      time->Thu Oct 19 18:27:23 2023
      type=PROCTITLE msg=audit(1697754443.937:123): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697754443.937:123): arch=c000003e syscall=262 success=no exit=-13 a0=ffffff9c a1=7f3f4c03dd38 a2=7f3f4bffe8b0 a3=0 items=0 ppid=1248 pid=1251 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
      type=AVC msg=audit(1697754443.937:123): avc:  denied  { getattr } for  pid=1251 comm="httpd" path="/var/www/html/index.html" dev="vda4" ino=16857024 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
      ----
      time->Thu Oct 19 18:27:23 2023
      type=PROCTITLE msg=audit(1697754443.937:124): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
      type=SYSCALL msg=audit(1697754443.937:124): arch=c000003e syscall=262 success=no exit=-13 a0=ffffff9c a1=7f3f4c03de18 a2=7f3f4bffe8b0 a3=100 items=0 ppid=1248 pid=1251 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
      type=AVC msg=audit(1697754443.937:124): avc:  denied  { getattr } for  pid=1251 comm="httpd" path="/var/www/html/index.html" dev="vda4" ino=16857024 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
      ----
      ...output omitted...

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

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

      [root@serverd ~]# ls -aZ /var/www/html/
      system_u:object_r:httpd_sys_content_t:s0 .
      system_u:object_r:httpd_sys_content_t:s0 ..
         unconfined_u:object_r:admin_home_t:s0 index.html

      The index.html file does not have the correct context.

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

      [root@serverd ~]# restorecon -v /var/www/html/index.html
      Relabeled /var/www/html/index.html from unconfined_u:object_r:admin_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    16. Confirm that you can now access the index.html page.

      [root@serverd ~]# curl http://localhost/index.html
      <html><body>Hello, World! from serverd</body></html>
    17. Disable SELinux denial auditing.

      [root@serverd ~]# semodule -B
  3. Confine the users on the serverd machine to prevent them from using the sudo and su commands. Further, they must not be able to run programs in the /tmp/ directory or in their home directory. These restrictions do not apply to the root user.

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

    1. Change the default mapping between the Linux users 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 the /tmp/ directory or their home directory, set the SELinux user_exec_content Boolean to the off value.

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

      [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: error initializing audit plugin sudoers_audit
      [student@serverd ~]$
    5. Confirm that you cannot execute programs in the /tmp or /home/student directories. 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:

    • Username: operator2

    • Password: redhat

    • Supplementary group: wheel

    Map the operator2 user to a confined SELinux user that has access to the su and sudo commands. Additionally, the operator2 user must be able to log in by using SSH.

    1. Log out of the serverd machine and log in as the root user.

      [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 the on value so that sysadm_u SELinux users can log in by using SSH.

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

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

      [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 the 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 the student user 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 the serverd machine. 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 the serverd machine as the student user. 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         3624 pts/0    Ss     0:00 -bash
    3. Retrieve the context type of the /usr/bin/passwd binary file.

      [student@serverd ~]$ ls -Z /usr/bin/passwd
      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 do not want to change your password; you just want to inspect the context of the process.

      [student@serverd ~]$ passwd
      Changing password for user student.
      Current password:
    5. Open a new terminal on the workstation machine and log in to the serverd machine as the root user.

      [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       3766 pts/0    00:00:00 passwd
    7. Install the setools-console package to get the sesearch command.

      [root@serverd ~]# dnf install setools-console
      ...output omitted...
      Is this ok [y/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 the student user's 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
      type_transition user_t passwd_exec_t:process passwd_t;
    9. Redirect the output of the previous command to the /home/student/rule file. When done, log out of the serverd machine.

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

      In the other terminal, quit the passwd command and log out of the serverd machine.

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

Evaluation

As the student user on the workstation machine, use the lab command to grade your work. Correct any reported failures and rerun the command until successful.

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

Finish

As the student user on the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

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

Revision: rh415-9.2-a821299