Issue #6 April 2005

Taking advantage of SELinux
in Red Hat® Enterprise Linux®


The release of Red Hat Enterprise Linux 4 debuts the first commercially supported inclusion of Security-Enhanced Linux (SELinux). An installation of Red Hat's latest enterprise operating system has SELinux installed and enabled by default. In the past SELinux has been criticized for a lack of commercial support, many big sites were unable to use it due to the lack of support (Fedora Core 3 doesn't have the support that they require). Now in Red Hat Enterprise Linux 4, SELinux is a supported part of the OS, and such objections to the use of SELinux have gone away. SELinux is now widely regarded as being suitable for the largest sites.

The targeted policy

The targeted policy is one of two policy types available with SELinux, the other being the strict policy. Red Hat Enterprise Linux 4 does not include support for the strict policy, but you may use it on a Fedora Core 3 system. The targeted policy was introduced in Fedora Core 3. Its aim is to provide additional security to some of the more commonly used daemons: httpd, dhcpd, mailman, named, portmap, nscd, ntpd, portmap, mysqld, postgres, squid, syslogd, winbind, and ypbind by employing Mandatory Access Control (MAC) rules. These daemons run in their own domain such as httpd_t for httpd and named_t for named. Other daemons on the system which do not have policy written specifically for them run in the domain unconfined_t. Daemons and system processes running in the unconfined_t domain only use the standard Linux Discretionary Access Control (DAC) method of access control as the SELinux policy grants all access. In SELinux access is granted to processes on a per-domain basis, each domain has a set of operations it may perform on each type of file, directory, or other resource.

The strict policy has every program running in a restrictive domain. It is not as easy to use, and the aim of the targeted policy is to increase security in the most important areas without reducing usability.

To determine if you're running the targeted policy, verify the following:

  • The file /etc/selinux/config should contain the line SELINUXTYPE=targeted, but note that this instructs the computer which policy to use at boot. If you change the machine between different policies, leave the SELINUXTYPE variable with a different value than the running policy before you reboot.
  • Running the id command should return something similar to
    uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:system_r:unconfined_t

The final part of root's security context tells us that the root shell is running in the unconfined_t domain, indicating that the targeted policy is in use. On a system running the strict policy a root shell will have the SELinux context of either root:staff_r:staff_t or root:sysadm_r:sysadm_t. You can also run the id -Z command to see your security context without the Unix UID/GID information (useful for shell scripts).

The daemons that have policy written for them will run in their own domains by default, but the administrator may configure them to run in the domain unconfined_t by specifying that they should not have a domain transition when executed. For example the command setsebool -P httpd_disable_trans 0 causes the httpd process to run in domain unconfined_t. Every daemon has a boolean to cause it to run in the unconfined_t domain. This can be used if the administrator is unable to get it working correctly in its own domain (although it is recommended that for best security the policy be modified if necessary to permit the daemon in question to run in a restrictive domain). Running daemons in the unconfined_t domain in this manner reduces the security of the system and should be avoided if possible.

Changing the values of booleans can be done with the setsebool command or with the program system-config-securitylevel. When using setsebool make sure you use the -P option if you want the change to be preserved across reboots.

To view the values of booleans use the getsebool command. To retrieve the value of a single bool specify the name on the command line, for example getsebool httpd_disable_trans. To view the values of all booleans use the getsebool -a command.

The easiest way of changing the booleans is through the system-config-securitylevel command as shown in Figure 1, Change the values of booleans. The httpd server has more booleans than most daemons because it is very configurable, and the configuration of the SELinux policy needs to match the configuration of the daemon.

Probably the most commonly used booleans in the targeted policy will be the ones to disable the SELinux protection for daemons that have been configured in a way that does not work well with SELinux. We don't recommend that you enable such booleans. They are only provided as emergency measures. If business requirements force you to run a daemon in a way that SELinux can't restrict, disabling the protection for that daemon is much better than disabling it for the entire system.

Change the values of booleans
Figure 1. Change the values of booleans

The policy files for the daemons when using the targeted policy is located in the /etc/selinux/targeted/src/policy/domains/program/ directory. The policy source files are commonly known as .te files which represent the naming convention such as syslogd.te.

A policy, or .te file, contains the rules for the associated domain. The syslogd.te file, for instance, defines the rules for the operation of the domain syslogd_t including operations such as logging to the console, modification and creation of log files, and remote logging, to name a few.

The policy file must match the file contexts, or .fc file located in /etc/selinux/targeted/src/policy/file_contexts/program/. File contexts files list the security contexts which must be applied to files and directories that the daemon uses. For example, the file named.fc contains:

/var/named(/.*)?                system_u:object_r:named_zone_t
/var/named/data(/.*)?           system_u:object_r:named_cache_t

The first line tells us that the /var/named/ directory is of the type named_zone_t. The second line tells us that the /var/named/data/ directory has the type named_cache_t.

/usr/sbin/named         --      system_u:object_r:named_exec_t

Tells us that the named executable is of type named_exec_t. The naming convention for daemon entry point executables is X_exec_t where X is the name of the daemon domain.

This causes a transition from the domain unconfined_t to the daemon domain (named_t in this example) when the daemon is executed. When using the strict policy daemons have to be started from an administrative session (role sysadm_r and domain sysadm_t) for correct operation. With the targeted policy, this is not an issue as unconfined_t is the only domain used for user logins (either administrator or a regular user).

The main policy file for named is named.te which contains the rules to permit access to the named_t domain as well as to define the domain and cause transitions to it. The most significant line in named.te is:

daemon_domain(named, `, nscd_client_domain')

This defines the domain named_t and permits it to perform all the basic operations that daemons perform such as writing a pid file to /var/run, forking a child process, logging to syslog, etc. It also has policy to cause an automatic domain transition from unconfined_t to named_t when an executable of type named_exec_t is executed.

Objectives of the Targeted Policy

The targeted policy was developed because the strict policy was considered to be too difficult for many system administrators to manage. When SELinux was initially introduced into Fedora Core 2, there was some negative feedback about the ease of use. With the release of Fedora Core 3, the targeted policy was the default, and there were very few complaints. Common estimates suggest that at least two million people are using Fedora Core 3 without even realizing that they are using SELinux. Their machine does what they want it to do, and they don't notice that daemons are not permitted to perform certain operations—those operations are not performed by daemons in the normal operation of a system with a typical configuration.

The general aim of policy development is that the strict policy will become easier to configure and better tuned for default configurations while the targeted policy will get an increasing number of targets to support more daemons. Through these developments the targeted and strict policies can be considered to be converging as the strict policy becomes easier to use and the targeted policy becomes more strict. But it seems unlikely that we will be able to merge the policies in the foreseeable future. The fundamental difference between strict and targeted is that strict uses the identity and role features of SELinux while targeted does not.

Some of the usability features of the targeted policy derive from many of the daemons running in the unconfined_t domain. Eventually we hope to get most of the daemons in question working well in more restrictive domains. The main benefit, however, in terms of the usability of the targeted policy is in the lack of restrictive domains for user sessions. It seems likely that the demand for this feature will exist for a long time. Therefore merging the strict and targeted policies will not be possible.

Supported configuration changes

Within the targeted policy, significant changes will break the support agreement for Red Hat Enterprise Linux. This means modifying the policy for daemons (particularly if such changes involve reducing access) and adding new domains for programs that are part of Red Hat Enterprise Linux. Adding new changes for programs that are not part of Red Hat Enterprise Linux may be OK as long as any bugs which are reported do not concern the programs in question.

If you go outside the supported configuration either through excessive changes to the targeted policy or through using the strict policy, support for SELinux features will be provided through GPS (Red Hat consulting). For support on issues unrelated to SELinux you may have to put SELinux in permissive mode when reporting problems.

Strict policy support

The Red Hat Enterprise Linux 4 release only contains the policy packages for the targeted policy because it is the only policy supported through the Global Support Services.

Packages for the strict policy will be available on the Red Hat website for organizations that have a policy of having all their system software come from the one source. They can get the strict policy from Red Hat, it just won't be supported through the usual support processes Anyone who wants to run SELinux on a Red Hat Enterprise Linux 4 system will be able to download the package selinux-policy-strict (and selinux-policy-strict-sources if they want to modify the policy source) and convert their system to the strict policy.

To convert a Fedora or Red Hat Enterprise Linux 4 system to the strict policy you only have to install the strict policy package and run system-config-securitylevel in an X session. You will then see a tab to configure SELinux. The SELinux tab features a drop-down list box that allows you to select between the installed policies as shown in Figure 2, Select between installed policies.

Select between installed policies
Figure 2. Select between installed policies

When you select to change between policies you will be asked to confirm the choice as shown in Figure 3, Confirm choice.

Confirm choice
Figure 3. Confirm choice

After selecting this option, you should reboot the machine at the earliest convenient time. Early in the boot process the script /etc/rc.sysinit will relabel the file system with the correct labels for the new policy type. Currently the configuration file /etc/selinux/config has one field for which type of policy is to be used, indicating which will be used on the next boot. The same field is used by some applications to determine which policy is currently running. So in the period between changing the policy through system-config-securitylevel and rebooting to apply the change, some programs may not operate in the desired manner as their idea of the running policy will not match reality. This is not a security issue as they will fail closed, but it may be a usability issue. One consequence of having the running policy not match the policy that is configured for the next boot is that cron jobs will not run.

The process of relabeling the file system involves comparing the fully qualified path name of each file on the system with a set of regular expressions such that the best match will indicate which security context should be assigned to the file. Thus the file system relabel process involved with converting between strict and targeted policies. This process will take at least as much time as find / and maybe as much as twice that due to the amount of computation taken for regular expressions. With a typical Red Hat Enterprise Linux or Fedora install on modern hardware this should only take a few minutes. If you have many of your own files installed then it will take proportionally longer.

If you have a server with millions of files with the same security context on their own file system, then it's best to use the context mount option to label them. This saves the time taken for a relabel and also saves the storage requirements for the security labels. For example the Squid cache files are labeled as system_u:object_r:squid_cache_t. If you had a large Squid server with a file system devoted to Squid, then you could put fscontext=system_u:object_r:squid_cache_t in the file system options field in the /etc/fstab file.

Red Hat Enterprise Linux 4 systems which use the strict policy will only be supported for non-SE functionality. Customers who make such modifications to their systems may be requested to put SELinux in permissive mode and reproduce the problem when making a support call for issues that are not directly related to SELinux. Permissive mode is when SELinux reports that it would not permit an operation but does not actually prevent the operation from occurring. Permissive mode is used for development of SELinux policies and for many types of testing. To quickly determine whether SELinux is the cause of a problem it can be put in permissive mode by the command setenforce 0 and then put back in enforcing mode with setenforce 1 after the test is complete. Note that it is not recommended that you put a production machine into permissive mode.

At this time support for the strict policy is only provided through GPS (the Red Hat consulting division). The regular support channels will not accept calls about it, and the guarantees about response time also do not apply. The strict policy is not on the Red Hat Enterprise Linux 4 CDs and is officially not part of the distribution.

The /etc/selinux/ directory

In Fedora Core 3 the SELinux base directory was changed to /etc/selinux/, and this is the location that is used for Red Hat Enterprise Linux 4 and will be used for all future releases. In the directory /etc/selinux/targeted/ you will find the files for the targeted policy. If you are running the strict policy, you will have the /etc/selinux/strict/ directory. By default, the policy sources are not installed. To install the policy sources, you need the selinux-policy-targeted-sources package (if running the strict policy, you - need the selinux-policy-strict-sources package). The installation of this package results in the /etc/selinux/targeted/src/ (or strict/src/) directory being installed. Here (under the policy directory) you will find the policy source.

User roles in the targeted policy

Under the targeted policy, there is no real use of user roles and domains. All user identities are permitted to use the role system_r, and thus identities and roles play no part in SELinux access control. Under the strict policy, every user who is significant to the system security policy (one category of which is users who are granted administrative rights) needs an entry in the users file to specify the roles which they are permitted to assume. With the targeted policy this aspect of policy configuration is not needed.

Development of other policies

The design of SELinux has all configuration options in the SELinux policy, and no configuration options are compiled into binaries. This means that the complete configuration of SELinux can be changed without changing any programs. Administrators of Red Hat Enterprise Linux 4 systems are free to build their own policy that is not based on either the strict or targeted policies. But again, this would be outside the Red Hat Enterprise Linux 4 support contracts.

About the authors

Faye Coker is a part-time system administrator. Russell Coker works for Red Hat on SELinux.