Controlling SELinux

Controlling SELinux entails three primary operations:

  • Switching the SELinux mode

  • Loading a security policy

  • Labeling files

The following subsections explain how to perform these operations.

Tip

The available commands and the associated command options provided by a given implementation of SELinux may differ a bit from those described in the following subsections. When you encounter such differences, you should check your system man pages and other available documentation to understand the operation of your system.

Switching Modes

If your Linux kernel was compiled with the NSA SELinux Development support option, you can specify the SELinux operating mode that should be entered when your SELinux system is booted. And, unless the SELinux security policy specifies otherwise, you can dynamically change the operating mode of a running SELinux system. Additionally, if your Linux kernel was compiled with the NSA SELinux boot parameter option, you can entirely disable SELinux via a boot parameter. The following subsections explain how to do so.

Setting the initial operating mode

The initial operating mode of an SELinux system can be set via the boot parameter enforcing. To boot the system into enforcing mode, assign this boot parameter the value 1; to boot the system into permissive mode, assign this boot parameter the value 0.

If you use GRUB to boot your system and want the system to automatically boot into enforcing mode, you might specify a kernel directive such as the following in your GRUB configuration file (generally, /boot/grub/grub.conf):

kernel /vmlinuz-2.6.4-1.305 ro root=LABEL=/ enforcing=1

If you use LILO to boot your system and want the system to automatically enter permissive mode after booting, you might specify an append directive such as the following in your LILO configuration file (generally, /etc/lilo.conf):

append="enforcing=0"

Whether you use GRUB or LILO, you may find it convenient to configure two boot configurations: one booting into enforcing mode and another booting into permissive mode. Doing so makes it easy to interactively choose the SELinux mode each time the system is booted.

GRUB optionally supports interactive editing of boot configurations. If you use GRUB, you may find it convenient to specify only an enforcing-mode boot configuration. When you want to boot the system into permissive mode, you can interactively edit the kernel directive to specify the value 0 for the enforcing option.

Warning

If you specify multiple boot configurations, and your system resides in a hostile environment, be sure to configure the boot manager to load the enforcing-mode configuration by default; otherwise, if someone untrained in SELinux or too much in a hurry reboots your system, it will enter permissive mode when booted and may be compromised.

To ameliorate the difficulty of troubleshooting an inaccurate or incomplete TE file in enforcing mode, you can install two kernels on your system: one compiled without the NSA SELinux Development support option and one compiled with the option. To help ensure that the system remains secure under normal circumstances, specify the configuration without the NSA SELinux Development support option as the default boot configuration. When you need to troubleshoot the system, you can reboot the system using the alternate kernel compiled with the NSA SELinux Development support option.

If you’re especially concerned about security, you may feel that including a kernel capable of permissive mode in your system’s boot configuration is too risky. In that case, you can prepare a boot disk or boot CD containing a permissive kernel and boot the system from your external media when troubleshooting is necessary.

You may find it impractical to reboot your system to perform troubleshooting. Indeed, a popular Linux mantra has it that “rebooting is only for installing new hardware.” In this case, you may find it necessary to maintain a clone of your production system, so that you can verify that activities such as installation of a new software package will work correctly and not interfere with system operation.

Dynamically setting the operating mode

Unless your SELinux security policy or the absence of the NSA SELinux Development support option dictate otherwise, you can set the operating mode of a running SELinux system dynamically. To ensure system integrity, the SELinux security policy prohibits nonprivileged users from dynamically setting the SELinux operating mode. Even the root user cannot do so unless operating within the sysadm_r role. The section of this chapter titled “Changing Roles” explains user roles and how to enter the sysadm_r role. If you possess the necessary privileges, you can dynamically set the SELinux operating mode either by manipulating a file within the /selinux filesystem or by issuing a special command.

The /selinux filesystem is a virtual filesystem resembling the familiar /proc or /sys filesystem. That is, it looks just like a filesystem but doesn’t reside on a hard drive or other physical media. Instead, it’s automatically generated by the kernel. The file /selinux/enforce indicates the current SELinux mode. Manipulating the file changes the current SELinux mode.

You can determine the current SELinux mode by issuing the command:

cat /selinux/enforce

The value that is displayed indicates the current mode: the value 0 indicates permissive mode and 1 indicates enforcing mode.

To enter enforcing mode, issue the command:

echo "1" > /selinux/enforce

Similarly, to enter permissive mode, issue the command:

echo "0" > /selinux/enforce

Many users find it inconvenient to directly access or modify the contents of the /selinux/enforce file. SELinux implementations provide commands that enable a properly privileged user to determine, or set, the current SELinux mode. In earlier SELinux releases, the command used to determine the current SELinux mode was avc_enforcing. Issuing this command printed the value “permissive” or “enforcing” according to the current SELinux mode. And, generally, the command avc_toggle was available to toggle the current SELinux mode, changing from permissive to enforcement or vice versa.

Under the current SELinux release, which breaks with tradition, the command getenforce reports the current SELinux mode as “permissive” or “enforcing.” The setenforce command changes the current SELinux mode. However, unlike the avc_toggle command, the setenforce command does not toggle the current mode. Instead, the setenforce command takes an argument that specifies the desired SELinux mode: 0 for permissive mode and 1 for enforcing mode. For instance, to enter permissive mode under Fedora Core 2, you issue the command:

                  setenforce 0

Disabling SELinux at boot time

If a Linux kernel was compiled with the NSA SELinux boot parameter option, it’s possible to completely disable SELinux at boot time. To do so, specify the boot parameter and value selinux=0 in the boot configuration, or interactively specify this parameter-value pair in response to a boot prompt or menu.

By disabling SELinux, you preclude it from prohibiting actions based on its security policy and from generating log entries. You also avoid the overhead entailed by SELinux itself, which some estimate consumes roughly seven percent of CPU resources. In essence, your system operates as though it were using a non-SELinux kernel.

You may find it convenient to disable SELinux when SELinux is operating improperly or entirely failing to operate. Booting in disabled mode may enable you to troubleshoot and repair the problem.

However, when SELinux is disabled, it’s not available to write appropriate file labels for newly created files, including files replaced after editing. Consequently, your system almost certainly will not operate correctly if you subsequently boot with SELinux enabled. To avoid this problem, you must relabel the filesystems—or at least all new files—before booting the system with SELinux enabled. The section of this chapter titled “Labeling Files” explains how to do so.

Loading the SELinux Security Policy

If you configure your system to boot into enforcing mode, it will automatically load the SELinux security policy at boot time. However, you may find it necessary or convenient to load the SELinux security policy at another time. For instance, you may modify the security policy and desire to replace the current security policy with the modified policy. This section explains how to load the security policy and perform several related operations.

The SELinux Makefile

As explained in Chapter 5, the /etc/security/selinux/src/policy directory contains a Makefile and related files that enable a system administrator to manipulate the security policy. SELinux prevents ordinary users from manipulating the security policy; only the root user in the sysadm_r role can manipulate the policy.

Tip

If your system does not include the src/policy directory and the Makefile that resides there, it’s likely that you’ve installed SELinux only partially. For instance, under Fedora Core 2, it’s likely that you haven’t installed the checkpolicy and policy-sources RPM packages.

You may choose to delete the policy source files from your system. Doing so may complicate the work of an intruder seeking a way to circumvent the SELinux security policy.

The Makefile supports five operations related to the security policy. In addition, it supports one operation related to file labeling, which is explained in the following section. Table 4-1 summarizes the operations supported by the Makefile, which are known as targets.

Table 4-1. Policy Makefile targets

Make target

Compiles the policy from source?

Installs the policy?

Loads or reloads the policy?

policy

Yes

No

No

install

Yes

Yes

No

load

Yes

Yes

Yes

reload

Yes

Yes

Yes

relabel

No

No

No

Tip

If you’re not familiar with Makefiles and their use, I suggest that you consult Managing Projects with Make (O’Reilly).

The three steps that can be performed through the Makefile are:

Compiles the policy from source

Checks the syntax of the policy source files and verifies that no policy constraints are violated.

Installs the policy

Creates the binary SELinux policy.

Loads or reloads the policy

Currently, the load and reload targets work the same way. Each loads the binary SELinux policy into the running kernel and begins using it to make security decisions.

To use the Makefile to perform a supported operation, follow this procedure:

  1. Be sure your current role is sysadm_r. The section “Routine SELinux System Use and Administration” of this chapter explains how to do so:

    # id -Z
    root:staff_r:staff_t# newrole -r sysadm_r
    Authenticating root.
    Password:
    # id -Z
    root:sysadm_r:sysadm_t

    If you’re not logged in as the root user, issue the su command to become the root user:

    su -

    Fedora Core automatically transitions you to the sysadm_r role when you issue the su command. If you’re not using Fedora Core, you must explicitly transition to the sysadm_r role:

    newrole -r sysadm_r
  2. Change the current working directory to /etc/security/selinux/src/policy:

    cd /etc/security/selinux/src/policy
  3. Invoke the desired operation:

    make target

    where target is the desired operation. For instance, to reload the security policy, issue the command:

    make reload
  4. Observe any error messages that appear on the console and take appropriate action.

Depending on the target you specify, the Makefile invokes one or both of the following SELinux utilities:

checkpolicy

The SELinux policy compiler

load_policy

A utility that loads the SELinux binary policy into the running kernel

It’s generally best to use the Makefile to perform policy-related operations. But, you may find it useful or necessary to understand how the Makefile does its work. The following sections explain the main utilities invoked by the Makefile: checkpolicy and load_policy.

The SELinux policy compiler (checkpolicy)

The SELinux policy compiler checkpolicy reads an SELinux policy source file and creates a binary policy file. In preparation for policy compilation, the SELinux Makefile provides the compiler with a single policy source file that includes all the installed TE files and other policy source files. The Makefile also expands M4 macros contained in those files.

The SELinux policy compiler has the following syntax:

checkpolicy [-b] [-c policyvers] [-d] [-o output_file] \
  [input_file]

The -b option instructs the policy compiler to read a binary policy file (contained in a file named policy) rather than a source policy file. This flag is rarely used.

The -c flag specifies the policy version number. If the flag is omitted, the latest policy version is assumed.

The -d option instructs the policy compiler to enter debug mode after it loads the policy.

The -o option specifies the name of the binary policy file that the compiler will write.

The input_file argument specifies the name of the policy source file that the compiler will process. If the argument is omitted, the compiler reads the policy.conf file (unless the -b option appears, in which case the compiler reads the binary policy file named policy).

For more information on the policy compiler and the compilation process, see the paper “Configuring the SELinux Policy,” by Stephen Smalley, available at http://www.nsa.gov/selinux/info/docs.cfm.

The load_policy utility

The load_policy utility reads a binary policy file, the name of which is specified as a command argument, and loads the policy into the running kernel. The utility provides no other arguments or options.

Labeling Filesystems and Files

As explained in Chapter 3, SELinux requires that files be labeled with extended attributes indicating their security context. Available filesystems are typically labeled when SELinux is installed.

It’s not routinely necessary to relabel filesystems and files after installation. However, it sometimes is necessary to do so. For instance, installation of a new filesystem may require the filesystem to be labeled. Or booting a system from a non-SELinux kernel may result in the creation of unlabeled files or the removal of labels from labeled files. Under such circumstances, you can use the Makefile in /etc/security/selinux/src/policy to label or relabel all available filesystems. Alternatively, you can use any of several commands to label or relabel just the filesystems or files that lack proper labels. This section explains how to perform these operations.

Tip

Some filesystem types do not support the extended attributes used to store file context labels. The src/policy/genfs_contexts file provides default contexts for files residing in such filesystems.

Depending on the size of the system’s hard drives and the number of files they store, the relabeling operation may require many minutes, perhaps more than an hour. When only a few files require relabeling, it’s inefficient to relabel by using the Makefile. In such cases, it’s better to perform the relabeling by using an SELinux utility. The next section explains how to do so.

Using the Makefile to label or relabel filesystems

To relabel all available filesystems by using the src/policy Makefile, follow this procedure:

  1. Be sure your current role is sysadm_r. The section “Routine SELinux System Use and Administration” of this chapter explains how to do so:

# id -Z
root:staff_r:staff_t
# newrole -r sysadm_r
Authenticating root.
Password:
# id -Z
root:sysadm_r:sysadm_t
  1. If you’re not logged in as the root user, issue the su command to become the root user:

su -
  1. Fedora Core automatically transitions you to the sysadm_r role when you issue the su command. If you’re not using Fedora Core, you must explicitly transition to the sysadm_r role:

newrole -r sysadm_r
  1. Change the current working directory to /etc/security/selinux/src/policy:

cd /etc/security/selinux/src/policy
  1. Invoke the relabel operation:

make relabel
  1. Observe any error messages that appear on the console and take appropriate action.

Using commands to label or relabel files or filesystems

SELinux provides several utilities that report or manipulate file labels. The utilities differ primarily in whether they operate on files or filesystems and whether they label by using a fixed, specified context or by using a specification file. One or another of the utilities is apt to be more convenient in any particular situation. The available utilities include:

/usr/bin/chcon

Labels one or more files with a specified security context

/sbin/fixfiles

Labels all available filesystems according to the contents of the standard specification file, src/policy/file_contexts/file_contexts

/sbin/restorecon

Labels one or more files according to the contents of the standard specification file, src/policy/file_contexts/file_contexts

/usr/sbin/setfiles

Labels one or more files or filesystems according to the contents of a specification file

The following subsections explain each utility in more detail.

The chcon utility

The chcon utility labels one or more filesystems with a security context. The command has two forms. The first form is used to label a file with a specified security context. The second form is used to label a file with the security context associated with a specified reference file.

The first form has this syntax:

chcon [options] context 
                     path...

For the moment, please ignore the command options. The remaining arguments represent a security context and one or more paths to be labeled or relabeled. For example, to set the security context of the files /etc/hosts and /etc/hosts.allow to system_u:object_r:etc_t, issue the command:

chcon system_u:object_r:etc_t /etc/hosts /etc/hosts.allow

The second form has this syntax:

chcon [options] --reference=rfile path...

The security context associated with the reference file, rfile, is used to label or relabel the specified paths. For example, to set the security context of the files /etc/hosts.allow and /etc/hosts.deny to the current security context of the file /etc/hosts, issue the command:

chcon --reference=/etc/hosts /etc/hosts.allow /etc/hosts.deny

In addition, the chcon utility supports several options:

-c, —changes

Print a message for each change made.

-h, —no-dereference

Operate on symbolic links instead of files they reference.

-f, —silent, —quiet

Suppress noncritical error messages.

-R, —recursive

Change files and directories recursively.

-r, —role ROLE

Set role ROLE in the target security context.

-t, —type TYPE

Set type TYPE in the target security context.

-u, —user USER

Set user USER in the target security context.

-v, —verbose

Print a message for each file processed.

—help

Print a help message and then exit.

—version

Print version information and then exit.

The fixfiles utility

The fixfiles utility labels all available filesystems according to the contents of the standard specification file, src/policy/file_contexts/file_contexts. The form of the command is:

fixfiles [check | restore | relabel]

That is, exactly one of the following arguments must appear:

check

Show any incorrect file labels, but do not change any file labels.

restore

Change the labels of any incorrectly labeled files.

relabel

Relabel all available filesystems.

For example, to check the file labels on all mounted filesystems, issue the command:

fixfiles check

The restorecon utility

The restorecon utility labels one or more files according to the contents of the standard specification file, src/policy/file_contexts/file_contexts. The command has the following form:

restorecon [-n] [-v] path...

One or more path names must be specified as arguments. For example, to label the file /etc/hosts according to the standard specification file, issue the command:

restorecon /etc/hosts

The command options have the following meanings:

-n

Do not change any file labels; merely print the changes that would be made.

-v

Show changes to file labels.

The setfiles utility

Whereas the fixfiles utility labels all available filesystems, the setfiles utility labels one or more specified filesystems. The command has the following form:

setfiles [options] spec_file 
                     path...

The spec_file argument specifies the file containing the specifications used to determine file labels. It has the same form as the FC files, which will be described in Chapter 5. The path argument specifies the files to be labeled. For example, to label the /etc/hosts file using the specifications contained in the file src/policy/file_contexts/file_contexts, issue the command:

setfiles src/policy/file_contexts/file_contexts /etc/hosts

The available command options include:

-d

Show the specification that matched each file.

-n

Don’t change any file labels.

-q

Suppress noncritical messages.

-s

Take a list of files from standard input rather than use a pathname on the command line.

-v

Show changes in file labels if type or role is changed.

-vv

Show changes in file labels if type, role, or user is changed.

-W

Print warnings about specification entries that have no matching files.

Tuning Fedora Core 2 SELinux

Because of the SELinux policy language and Flask architecture, SELinux is highly flexible. A system administrator can tailor—or entirely replace—the standard SELinux security policy with a customized policy that better suits the local environment. However, some implementations of SELinux provide very simple means for tailoring policy operation. In particular, the Fedora Core 2 implementation of SELinux provides two convenient ways of tailoring SELinux operation:

  • Macros

  • Policy Booleans

The following subsections describe these means. If you’re using an SELinux implementation other than that associated with Fedora Core 2, you may find that your implementation provides similar features, though perhaps in a different way. And even if your SELinux implementation entirely lacks features like those described in the upcoming sections, the sections may suggest useful ways in which to modify your SELinux security policy. So you’re likely to find it worthwhile to read the sections, even though they deal specifically with the Fedora Core 2 SELinux implementation.

Tuning via macros

The file src/policy/tunable.te defines two to three dozen M4 macros that you can use to tailor the operation of SELinux. Doing so is simple: you merely comment or uncomment a macro definition.

M4 does not use the hash mark (#) to denote comments, as many other Linux programs do. Instead, M4 prefixes comments with the characters dnl (“do not list”), followed by a space. If you’ve configured Sendmail, which uses M4, you’re familiar with M4’s rather odd convention.

Table 4-2 summarizes the macros defined in tunable.te.

Table 4-2. Policy macros

Policy macro

Active by default?

Description

allow_user_direct_mouse

Yes

Allow regular users direct access to the mouse device file (otherwise allow only the X server to do so).

allow_user_dmesg

Yes

Allow users to run the dmesg command

allow_user_tcp_server

Yes

Allow users to run TCP servers (bind to ports and accept connection from the same domain and outside users). Disabling this Boolean forces FTP passive mode and may affect other protocols (including IRC if single_userdomain is defined).

allow_xserver_home_fonts

Yes

Allow X server to check for fonts in ~/.gnome or ~/.kde.

allow_ypbind

Yes

Allow ypbind to run with NIS.

direct_sysadm_daemon

Yes

Allow sysadm_t to start daemons directly.

ftp_home_dir

No

Allow FTP to read/write files in user home directories.

ftpd_is_daemon

Yes

Allow FTP to run from inetd instead of as a stand-alone daemon.

hide_broken_symptoms

No

Adds dontaudit rules for broken polices that are not security risks.

nfs_export_all_ro

No

Allow reading on any filesystem.

nfs_export_all_rw

Yes

Allow read/write/create on any filesystem.

nfs_home_dirs

Yes

Allow NFS home directories.

        nscd_all_connect

Yes

Allow all domains to access NSCD.

read_default_t

Yes

Allow ordinary users to read any file having type default_t.

readhome

Yes

Allow Mozilla to read files in the user home directory.

run_ssh_inetd

No

Allow SSH to run from inetd instead of as a daemon.

secure_levels

No

Allow only administrator to log in at the console and forbid direct access to disk devices.

single_userdomain

No

Make processes other than newrole and su run by a user domain stay in the same user domain.

ssh_sysadm_login

Yes

Allow SSH logins to the sysadm_r:sysadm_t security context; otherwise, remote SSH users cannot enter this context.

staff_read_sysadm_file

No

Allow staff_r users to search the system administrator’s home directory (generally /root) and read its files.

unlimitedServices

Yes

Allow processes under initrc and xinetd to run with all privileges.

unlimitedUsers

No

Allow users to have full access.

unrestricted_admin

Yes

Allow sysadm_t to do almost everything.

use_games

Yes

Allow users to run games.

user_can_mount

Yes

Allow users to execute mount command.

user_canbe_sysadm

Yes

Allow normal users to enter sysadm_r role.

user_net_control

Yes

Allow users to control network interfaces (also needs USERCTL=true).

user_rw_noexattrfile

Yes

Allow users to read/write noextattrfile (FAT, CDROM, FLOPPY).

writehome

Yes

Allow Mozilla to write files in the user home directory.

xdm_sysadm_login

Yes

Allow xdm logins as sysadm_r:sysadm_t.

Tip

The description of tunable.te macros given in Table 4-2 is based on the Test 2 release of Fedora Core 2. It’s possible—even likely—that the contents of the file will differ in subsequent releases.

To tailor the security policy using tunable.te, follow this procedure:

  1. Make the current working directory /etc/security/selinux/src/policy.

  2. Using a text editor, comment or uncomment macros in tunable.te, by adding or deleting the dnl token.

  3. Compile the policy sources and load a revised binary policy by issuing the command make reload.

Tuning via policy Booleans

Fedora Core 2 introduces Policy Booleans (generally referred to as simply Booleans), a new SELinux feature that enables modification of a running SELinux security policy. Booleans are true-false values that can be tested by security policy rules. The unique aspect of Booleans is that special commands can query and change their values at any time. The commands, of course, are available only to system administrators.

At the time of writing, the Fedora Core 2 security policy defines only one Boolean: user_ping . The value of the user_ping Boolean specifies whether ordinary users are permitted to use the ping command. Admittedly, this Boolean enables a rather trivial policy tweak. However, it’s likely that subsequent releases of Fedora Core 2 and releases of other SELinux implementations will include additional Booleans.

Two commands are used in working with Booleans:

change_bool

Changes the value of a Boolean.

show_bools

Prints all available Booleans and their values.

The change_bool command has the following form:

change_bool boolean [0|1]

where boolean is the name of the Boolean whose value is being set. The value 0 stands for false and 1 stands for true. For example, to set the value of the user_ping Boolean to false, issue the command:

change_bool user_ping 0

The show_bools command, which reports the value of available Booleans, requires no options or arguments. Typical output of show_bools follows:

# show_bools
user_ping --> active: 0 pending: 0

Notice that the output of the show_bools command distinguishes two values for each listed Boolean: the active value and the pending value. When setting Boolean values via change_bool, this distinction is not important. Internally, SELinux allows revised Boolean values to be designated in a way that enables the system administrator to cause the changes to several different values to take effect simultaneously. However, the change_bool command immediately commits changes to Booleans. Therefore, when using the change_bool command to set Boolean values, the active and pending values should always be the same.

Setting Booleans via the /selinux filesystem

Rather than use the change_bool command to set the value of a Boolean, you can manipulate nodes within the /selinux/boolean directory of the /selinux filesystem. The names of those nodes are identical to the names of the corresponding Booleans. For example, to set the value of the user_ping Boolean to false, issue the command:

                     echo 0 > /selinux/booleans/user_ping

Unlike changes made via the change_bool command, changes made via the /selinux filesystem do not immediately take effect. To commit the changes, issue the command:

                     echo 1 > /selinux/commit_pending_bools

All pending changes take effect immediately upon issuance of this command.

Get SELinux now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.