Table of Contents

SELinux

more @ http://feeds.feedburner.com/~r/RedHatMagazine/~3/272495315/

History

When SELinux was first developed, the goal was to confine as many system processes as possible to the least amount of privilege required. Fedora 2 was released with SELinux policy that confined users as well as system processes. We quickly realized that SELinux policy was not mature enough to handle a modern mainstream desktop operating system. After a quick redesign of the policy, we created “targeted” policy, replacing the previously named “strict” policy. The goal of targeted policy was to “target” certain processes in the operating system for confinement and leave the rest of the processes “unconfined.”

Logged-in user’s processes were unconfined in targeted policy. A logged-in user’s process is started by login programs (like login, sshd, or gdm) when the user provides authentication. In Red Hat® Enterprise Linux® 4, there were fifteen targeted applications that were confined, and in Red Hat Enterprise Linux 5 this grew to two hundred.

In Red Hat Enterprise Linux 5, we still did not confine the user. Strict policy was still provided, but few people used the confined user components. Multi Level Security (MLS) policy–which was developed for Red Hat Enteprise Linux 5–attains the highest level of security possible for a main line operating system used in military environments. It provides confinement for the users. MLS, however, only supports servers, so X-Windows applications did not benefit from this confinement.

The MLS development forced us to concentrate more on confining users, and we realized that we could take advantage of this confinement within targeted policy.

Customers/Partner engineers that were looking to work with MLS policy kept asking: How would you write policy for a logged in user who could only talk to a single port? How about a user who could only read a certain directory?

The two types of logged-in users we had developed for strict and MLS policy were user_t and staff_t. This was a problem because these users had basically the same interfaces/transitions and pretty much the same access.

staff_t was able to transition to sysadm_t, which was sort of a poor mans unconfined process. But trying to build a confined user policy out of either of these user types was impossible, since you needed to take lots of privileges away.

I reexamined the policy and decided it was necessary to create a least privileged user, a user that could login to the system with no access other than to read/write his home directory and use /tmp. This user would not be allowed to access the network, or run any setuid applications.

Customers also requested that the user not be able to execute files in his home directory. With this type of user as a base, customers could slowly add privileges to meet their needs.

The guest_t and xguest_t user types

In Fedora 8, we introduced the guest_t and xguest_t user types. The guest_t user has only the privileges necessary to login to a system via a terminal (Login, sshd, rshd, rlogind, and telnet). The xguest_t user has only the privileges required to login to an X-Windows system.

Once we had created these users, we began to find more possible uses for them. For example, at Red Hat, I have ssh access to people.redhat.com and people.fedoraproject.org. We ssh to these accounts and copy files there to set up http web pages, like so:

http://people.redhat.com/dwalsh

Files at this site are actually just files in my home/public_html directory on people.redhat.com. When I ssh to these machines, I really should not use the network to leave them, and I do not need to run any setuid applications while I am on them. So setting up these machines where all users are guest_t would make sense.

xguest_t also comes in handy for use on desktop machines. I have blogged about the use of xguest to confine my wife. [ Ed note.: No wives were harmed in the writing of this article. ] I extended xguest_t to transition to xguest_mozilla_t when running firefox. The xguest_mozilla_t domain is allowed to access http ports but nothing else. The xguest_t account allows me to lock down the system enough so that I know what processes are connecting to the internet. If the user downloads a spam application, it will not be allowed to run in the home directory, nor can it connect to the mail ports.

Other users have suggested using xguest_t for running games and other untrusted software applications. You could also set up an xguest user account to allow others to “borrow” your machine. In Fedora 8 and 9, there is an xguest rpm, which setups a kiosk mode user.

This “xguest” user can log in to your system from the console without a password when SELinux is in enforcing mode. The xguest rpm also sets up pam_namespace to create temporary home directories and /tmp directories, which are destroyed when the user logs out. We think this is an excellent way to run a kiosk machine. The login user can only browse the web (using firefox) and can not leave any apps around to attack other users that log into the system. Everything that user does on the machine is erased when they log out, so no one could grab any password information that might have been left behind.

You can try out xguest by executing:

 # yum install xguest

The user_t SELinux user type

For Fedora 9, we combined the strict policy with the targeted policy. We have enhanced the user_t and staff_t SELinux user and now allow you to setup these users in a targeted policy system.

The user_t SELinux user is the standard SELinux user. At Red Hat, we have a distribution of Red Hat Enterprise Linux that is given to all non-engineers by the IT department. Sales people, support, administration, and management staff are given machines installed with a version of Red Hat Enterprise Linux but are not usually given the root password. These are machines for people who do not want to administer their own boxes. The IT department is in charge of updating the software on these boxes and maintaining the security. If users want to add software or modify their machines they have to contact the help desk for an update.

Accounts like these should be set up to use the user_u SELinux user. user_u is a complete login user account, unlike xguest, and it has full networking so that the user can connect to any network port. It does not have the ability to run setuid applications without a transition.

setuid applications are executables that have a special flag set on them. This flag tells the kernel to run the application with the identity of the owner of the application rather then the identity of the person executing the program. Usually setuid apps are owned by root, so running as setuid application as a normal user allows you to gain privileges. Over the years, many setuid applications have had vulnerabilities that allowed root exploits of the system. user_t would not be allowed to run any of these applications.

Since the users of this machine have no reason to ever become root, they do not have the ability to run su, sudo, userhelper, or any other application that requires setuid. Even if you had a setuid shell program on your system, user_t would not be allowed to execute it. Additionally, user_t processes are not allowed to read a lot of system space, so you are somewhat protected from “snooping eyes” looking at how the system is running.

If you have a setuid application that you want the user to be able to run, you can write policy to allow the user_u account to transition to a different domain to execute the code. For example, xlock uses pam to verify the users password. pam executes /sbin/unix_chkpwd, a setuid application. policy allows a transition from user_u:user_r:user_t → user_u:user_r:chkpwd_t, which can run as root.

Like xguest , the user_u account can be set to disallow execution of programs in the home directory or /tmp.

 setsebool -P allow_user_exec_content=0

If you want to set up your system to try out the user account, you can execute the following command as root:

 # semanage login -m -s user_u USERNAME

or

 # usermod -Z user_u USERNAME

If you want to add a user with user_u, you can execute:

 useradd -Z user_u USERNAME

If you want all users on your system to default to user_u you would execute:

 # semanage login -m -s user_u __default__

The staff_t SELinux user type

The staff_t user is for users who need to do some system administration, but do not need to be fully unconfined. This is the user that I log in as every day. Staff_t is similar to user_t in that it has full networking and is only allowed to run setuid applications via a transition. staff_t has a transition to sudo so you can write policy to allow the staff_t user to transition to a confined root user via the sudo command. If I run any other setuid application, it will fail, including su.

I actually have a transition defined between the staff_t to unconfined_t. When I become root, I become the unconfined_t user. This allows me to manage my machines any way I want, but requires me to go through sudo to gain the privilege. We have a webadm_t policy available in Fedora 9 that can also be used for a “confined” root user.

My sudoers file has the following line in it:

 dwalsh	ALL=(ALL) 	TYPE=unconfined_t ROLE=unconfined_r ALL

To only allow this user to administer apache server I could use:

  dwalsh	ALL=(ALL) 	TYPE=webadm_t ROLE=webadm_r ALL

To try out the staff account, execute the following command as root:

  # semanage login -a -s staff_u -r s0-s0:c0.c1023 USERNAME

or

  # usermod -Z staff_u USERNAME

Configure the staff_u user to allow it webadm_r and/or unconfined_r by executing:

  # semanage user -m -R"unconfined_r webadm_r staff_r" staff_u

4 Effective Methods to Disable SELinux Temporarily or Permanently

Method 1: Disable SELinux Temporarily

To disable SELinux temporarily you have to modify the /selinux/enforce file as shown below. Please note that this setting will be gone after the reboot of the system.

 # cat /selinux/enforce
 1
 # echo 0 > /selinux/enforce
 # cat /selinux/enforce
 0

You can also use setenforce command as shown below to disable SELinux. Possible parameters to setenforce commands are: Enforcing , Permissive, 1 (enable) or 0 (disable).

 # setenforce 0

Method 2: Disable SELinux Permanently

To disable the SELinux permanently, modify the /etc/selinux/config and set the SELINUX=disabled as shown below. One you make any changes to the /etc/selinux/config, reboot the server for the changes to be considered.

 # cat /etc/selinux/config
 SELINUX=disabled
 SELINUXTYPE=targeted
 SETLOCALDEFS=0

Following are the possible values for the SELINUX variable in the /etc/selinux/config file

Following are the possible values for SELINUXTYPE variable in the /etc/selinux/config file. This indicates the type of policies that can be used for the SELinux.

Method 3: Disable SELinux from the Grub Boot Loader

If you can’t locate /etc/selinux/config file on your system, you can pass disable SELinux by passing it as parameter to the Grub Boot Loader as shown below.

# cat /boot/grub/grub.conf
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title Enterprise Linux Enterprise Linux Server (2.6.18-92.el5PAE)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-92.el5PAE ro root=LABEL=/ rhgb quiet selinux=0
initrd /boot/initrd-2.6.18-92.el5PAE.img
title Enterprise Linux Enterprise Linux Server (2.6.18-92.el5)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-92.el5 ro root=LABEL=/ rhgb quiet selinux=0
initrd /boot/initrd-2.6.18-92.el5.img

Method 4: Disable Only a Specific Service in SELinux - HTTP/Apache

If you are not interested in disability the whole SELinux, you can also disable SELinux only for a specific service. For example, do disable SELinux for HTTP/Apache service, modify the httpd_disable_trans variable in the /etc/selinux/targeted/booleans file.

Set the httpd_disable_trans variable to 1 as shown below.

# grep httpd /etc/selinux/targeted/booleans
httpd_builtin_scripting=1
httpd_disable_trans=1
httpd_enable_cgi=1
httpd_enable_homedirs=1
httpd_ssi_exec=1
httpd_tty_comm=0
httpd_unified=1

Set SELinux boolean value using setsebool command as shown below. Make sure to restart the HTTP service after this change.

 # setsebool httpd_disable_trans 1
 # service httpd restart