How to set up a system with SELinux confined users

Updated

User story

As an enterprise administrator I want my systems to follow the STIG rule Content from rhel7stig.readthedocs.io is not included.V-71971 so that my system will be fully confined without unconfined users.

I want one administrator user who can become root and manage the system, and other users restricted so that they can't become root.

Implementation

The following steps are described for a fresh installed system with Red Hat Enterprise Linux 7.

Confine regular users

Linux users can be assigned to SELinux users using the semanage login tool. By default, users are mapped to unconfined_u:

~]# semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

NOTE

system_u is a special user used only for system processes and it will not be listed in the future.

In order to change mapping for all Linux users, we need to modify the record with __default__ which represents all users without an explicit mapping.

~]# semanage login -m -s user_u -r s0 __default__
~]# semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

Since now, when any user but root logs in, their processes will run in the user_t domain.

~]# adduser user42
...
~]# ssh user42@localhost
user42@localhost's password:

[user42@localhost ~]$ id -Z
user_u:user_r:user_t:s0
[user42@localhost ~]$ ps axZ
LABEL                     PID TTY    STAT  TIME COMMAND
-                           1 ?      Ss    0:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
user_u:user_r:user_t:s0  2780 ?      S     0:00 sshd: user42@pts/1
user_u:user_r:user_t:s0  2781 pts/1  Ss    0:00 -bash
user_u:user_r:user_t:s0  2808 pts/1  R+    0:00 ps axZ

Now we can try if the user can become root:

~]# grep user42 /etc/sudoers
user42  ALL=(ALL)       NOPASSWD: ALL
~]# ssh user42@localhost
user42@localhost's password:

[user42@localhost ~]$ sudo -i
sudo: PERM_SUDOERS: setresuid(-1, 1, -1): Operation not permitted
sudo: no valid sudoers sources found, quitting
sudo: setresuid() [0, 0, 0] -> [1001, -1, -1]: Operation not permitted
sudo: unable to initialize policy plugin

And the same attempt in permissive mode:

~]# id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
~]# setenforce 0
~]# ssh user42@localhost
user42@localhost's password:

[user42@localhost ~]$ sudo -i
~]# id
uid=0(root) gid=0(root) groups=0(root) context=user_u:user_r:user_t:s0

Since in permissive mode SELinux policy is not enforced, user42 can become root, but we can see that the context remained user_t and didn't change to unconfined_t.

NOTE
If you need users to run TCP servers - to bind and accept connections

  • you need to set the selinuxuser_tcp_server SELinux boolean to on.
~]# setsebool -P selinuxuser_tcp_server on

NOTE
If you want to prevent Linux users in the user_t domain from executing
applications in their home directories and also other shared directories like /tmp,
you need to set the user_exec_content SELinux boolean to off.

~]# setsebool -P user_exec_content off
~]# ssh user42@localhost
user42@localhost's password:
[user42@localhost ~]$ cat >> myscript.sh <<EOF
#!/bin/bash
echo hello
EOF
[user42@localhost ~]$ chmod +x myscript.sh
[user42@localhost ~]$ ./myscript.sh
-bash: ./myscript.sh: Permission denied
[user42@localhost ~]$ chcon -t bin_t myscript.sh
chcon: failed to change context of ‘myscript.sh’ to ‘user_u:object_r:bin_t:s0’: Permission denied

Confine administrator

There are two basic methods how to confine the administrator user.

The administrator can be directly mapped to the sysadm_u SELinux user so that when such a user logs in, the session will be run in the sysadm_t domain. In this case you need to enable the ssh_sysadm_login SELinux boolean in order to allow users mapped to sysadm_u to log in using ssh.

~]# adduser -G wheel -Z sysadm_u admin1
~]# semanage login -l | grep admin
admin1               sysadm_u             s0-s0:c0.c1023       *
~]# setsebool -P ssh_sysadm_login on
~]# ssh admin1@localhost
[admin1@localhost ~]$ id -Z
sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
~]$ sudo -i
[sudo] password for admin1:
[root@localhost ~]# id -Z
sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
[root@localhost ~]# systemctl restart sshd
[root@localhost ~]#

The other way is to map administrator users to staff_u and configure sudo so that particular users can gain SELinux administrator role.

~]# adduser -G wheel -Z staff_u admin2
~]# semanage login -l | grep admin
admin1               sysadm_u             s0-s0:c0.c1023       *
admin2               staff_u              s0-s0:c0.c1023       *
~]# ssh admin2@localhost
[admin2@localhost ~]$ id -Z
staff_u:staff_r:staff_t:s0-s0:c0.c1023
[admin2@localhost ~]$ sudo -i
[sudo] password for admin2:
-bash: /root/.bash_profile: Permission denied
-bash-4.2# id -Z
staff_u:staff_r:staff_t:s0-s0:c0.c1023
-bash-4.2# systemctl restart sshd
Failed to restart sshd.service: Access denied
See system logs and 'systemctl status sshd.service' for details.

To allow the admin2 user to gain SELinux administrator role, you need to add the following rule to sudoers.

admin2  ALL=(ALL)  TYPE=sysadm_t ROLE=sysadm_r    ALL

NOTE
sudo can be configured using different tools, here we use visudo:

~]# visudo -f /etc/sudoers.d/administrators

admin2 can gain administrator role using sudo now.

~]# ssh admin2@localhost
[admin2@localhost ~]$ sudo -i
[sudo] password for admin2:
[root@localhost ~]# id -Z
staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
[root@localhost ~]# systemctl restart sshd
[root@localhost ~]#

References

SBR
Article Type