Chapter 5. Controlling and Maintaining SELinux

SELinux presents both a new security paradigm and a new set of practices and tools for administrators and some end-users. The tools and techniques discussed in this chapter focus on standard operations performed by administrators, end-users, and analysts. More complex operations, such as compiling a policy after a local change, are covered in Chapter 7 Compiling SELinux Policy.

5.1. End User Control of SELinux

In general, end users have little interaction with SELinux when Red Hat Enterprise Linux is running the targeted policy. This is because users are running in the domain of unconfined_t along with the rest of the system except the targeted daemons. This means that when you as an end-user come across a need to use a special SELinux tool or even to check and change the context for a file, it is likely to be when you are working with one of the targeted daemons. You can read more about the targeted daemons in Section 3.1 What is the Targeted Policy?.

In most situations, standard DAC controls stop you from doing what you are not permitted before you are stopped by SELinux, and you'll never generate an avc: denied message.

These sections cover the general tasks and practices that an end-user might need to do on Red Hat Enterprise Linux. Users of all privilege levels need to do these tasks as well.

5.1.1. Move or Copy Files

In file system operations, security context must now be considered in terms of the label of the file, the process touching it, and the directories where the operation is happening. Because of this, moving and copying files with mv and cp may have unexpected results.

Unless you tell it otherwise, cp follows the default behavior of creating a new file based on the domain of the creating process and the type of the target directory. Unless there is a specific rule setting the label, the file inherits the type from the target directory. The -Z user:role:type option allows you to specify what label you want the new file to have.

touch bar foo
ls -Z bar foo
-rw-rw-r--  auser   auser   user_u:object_r:user_home_t   bar
-rw-rw-r--  auser   auser   user_u:object_r:user_home_t   foo

# Doing a cp creates a file in the new location with the default
# type based on the creating process and target directory.  In
# this case, there not being a specific rule about cp and /tmp,
# the new file has the type of the parent directory:

cp bar /tmp
ls -Z /tmp/bar
-rw-rw-r--  auser   auser   user_u:object_r:tmp_t   /tmp/bar

# The -Z option allows you to specify the label for the new file:

cp -Z user_u:object_r:user_home_t foo /tmp
ls -Z /tmp/foo
-rw-rw-r--  auser   auser   user_u:object_r:user_home_t   /tmp/foo

The type tmp_t is the default type for temporary files.

Moving files with mv retains the type the file started with. This may cause problems, for example, if you move files with the type user_home_t into ~/public_html, httpd is not able to serve them until you relabel the file. You can read about file relabeling in Section 5.1.3 Relabel a File or Directory's Security Context.

CommandBehavior
mv The file retains its original label. This may cause problems, confusion, or minor insecurity. For example, the program tmpwatch running in the domain sbin_t might not be allowed to delete an aged file in /tmp because of the file's type.
cp A plain copy creates the new file following the default behavior based on the domain of the creating process (cp) and the type of the target directory.
cp -Z user:role:type The new file is relabeled as it is created based on the command line option. The extended GNU option --context is the same as -Z.

Table 5-1. Behavior of mv and cp

5.1.2. Check the Security Context of a Process, User, or File Object

In Red Hat Enterprise Linux, the -Z option is equivalent to --context, and can be used with ps, id, ls, and cp, which is explained in Table 5-1.

The ps command can create a lot of output, so this example is showing only a small sample. Most of the processes are running in unconfined_t, with a few exceptions. You can tell a process started from a root login by the role setting on the label, for example with one of the bash processes:

ps -Z
LABEL                             PID TTY          TIME CMD
user_u:system_r:unconfined_t    18543 pts/7    00:00:00 bash
user_u:system_r:unconfined_t    22846 pts/7    00:00:00 ps
ps -eZ
...
user_u:system_r:unconfined_t     1041 ?        00:00:00 udevd
user_u:system_r:unconfined_t     1511 ?        00:00:00 kjournald
user_u:system_r:unconfined_t     1512 ?        00:00:00 kjournald
user_u:system_r:syslogd_t        1873 ?        00:00:01 syslogd
user_u:system_r:unconfined_t     1877 ?        00:00:00 klogd
user_u:system_r:unconfined_t     1888 ?        00:00:34 irqbalance
user_u:system_r:portmap_t        1899 ?        00:00:00 portmap
user_u:system_r:unconfined_t     1919 ?        00:00:00 rpc.statd
user_u:system_r:unconfined_t     1952 ?        00:00:00 rpc.idmapd
...
user_u:system_r:unconfined_t    17252 ?        00:00:01 sshd
root:system_r:unconfined_t      17254 pts/1    00:00:00 bash
user_u:system_r:unconfined_t    17390 ?        00:00:04 gconfd-2
...
user_u:system_r:unconfined_t     1160 ?        00:00:00 firefox
user_u:system_r:unconfined_t     1541 ?        00:00:00 \
  run-mozilla.sh
user_u:system_r:unconfined_t     1558 ?        00:01:37 firefox-bin

For id, the -Z option is only usable by itself, it cannot be combined with other options. In this example, the change to root using su did not cause a change in role. In a stricter policy, su is capable of making a role change as well, i.e., from system_r to sysadm_r. This removes the step of using newrole following a su command:

# You are an ordinary user here:

whoami
auser
id -Z
user_u:system_r:unconfined_t

# Switching to root changes your UID:

su - root
Password:
whoami
root

# Only the SELinux user name changed, which has no effect in 
# the targeted policy.
id -Z
root:system_r:unconfined_t

Using the -Z option with ls groups together common long format information. The display choices focus on what you might want when considering the security permissions of a file. It displays mode, user, group, security context, and file name.

cd /etc
ls -Z h* -d
drwxr-xr-x  root root  system_u:object_r:etc_t        hal
-rw-r--r--  root root  system_u:object_r:etc_t        host.conf
-rw-r--r--  root root  user_u:object_r:etc_t          hosts
-rw-r--r--  root root  system_u:object_r:etc_t        hosts.allow
-rw-r--r--  root root  system_u:object_r:etc_t        hosts.canna
-rw-r--r--  root root  system_u:object_r:etc_t        hosts.deny
drwxr-xr-x  root root  system_u:object_r:hotplug_etc_t  hotplug
drwxr-xr-x  root root  system_u:object_r:etc_t        hotplug.d
drwxr-xr-x  root root  system_u:object_r:httpd_sys_content_t htdig
drwxr-xr-x  root root  system_u:object_r:httpd_config_t httpd

5.1.3. Relabel a File or Directory's Security Context

You may need to relabel a file when moving or copying into special directories related to the targeted daemons, such as ~/public_html directories, or when writing scripts that work in directories outside of /home.

There are two general kinds of relabeling operations, one where you are deliberately changing the type of a file, the other where you are restoring files to the default state according to policy. There are also relabeling operations that an administrator performs, and those are covered in Section 5.2.2 Relabel a File System.

TipTip
 

Since most of SELinux permission control in the targeted policy is type enforcement, you can primarily ignore the user and role information in a security label and focus on just changing the type. This saves you some keystrokes, and keeps you from worrying about the roles and users settings on your files.

NoteNote
 

If relabeling affects the label on a daemon's executable, you want to restart the daemon to be sure it is running in the correct domain. For example, if your /usr/sbin/mysqld has the wrong security label and this is fixed by a relabeling operation such as restorecon, you must restart mysqld after the relabeling. The executable file having the proper type of mysqld_exec_t ensures it transitions into the proper domain when started.

Use chcon when you have a file that is not the type you want it to be. You must know the new type you want instead:

# These directories and files are labeled with the default type 
# defined for file system objects created in /home:

cd ~
ls -Zd public_html/
drwxrwxr-x  auser  auser  user_u:object_r:user_home_t public_html/
ls -Z web_files/
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   1.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   2.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   3.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   4.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   5.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t   index.html

mv web_files/* public_html/
ls -Z public_html/
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t     1.html
...

# If you want to make these files viewable from a special user
# public HTML folder, they need to have a type that httpd has
# permissions to read, presuming the Apache HTTP server is configured
# for UserDir and the Boolean value httpd_enable_homedirs is 
# enabled.

chcon -R -t httpd_used_content_t public_html/
ls -Z public_html
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  1.html
...

ls -Z public_html/ -d
drwxrwxr-x  auser  auser  user_u:object_r:httpd_user_content_t \
public_html/

TipTip
 

If the file has no label, such as a file created while SELinux was disabled in the kernel, you need to give it a full label with chcon system_u:object_r:shlib_t foo.so. If you don't, you get an error about applying a partial context to an unlabeled file.

Use restorecon when you want to restore files to the policy default. There are two other methods to do this that work on the entire file system, fixfiles or a policy relabeling operation. These require you to be the root user. Cautions against both of these methods appear in Section 5.2.2 Relabel a File System.

This example shows restoring the default user home directory context to a set of files that have different types:

# These two sets of files have different types, and are
# being moved into a directory for archiving.  Their contexts
# are different from each other, and incorrect for a standard
# user's home directory:

ls -Z /tmp/{1,2,3}
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            /tmp/1
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            /tmp/2
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            /tmp/3
mv /tmp/{1,2,3} archives/
mv public_html/* archives/
ls -Z archives/
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            1
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  1.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            2
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  2.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t            3
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  3.html
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  4.html
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
  5.html
-rw-rw-r--  auser  auser  user_u:object_r:httpd_user_content_t \
index.html

# The directory archives/ is already the default type
# because it was created in the user's ~/ directory:

ls -Zd archives/
drwxrwxr-x  auser  auser  user_u:object_r:user_home_t  archives/

# Relabeling with restorecon uses the default file contexts set
# by the policy, so these files are labeled with the default 
# label for the directory they are in.

/sbin/restorecon -R archives/
ls -Z archives/
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    1
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    1.html
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    2
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    2.html
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    3
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    3.html
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    4.html
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    5.html
-rw-rw-r--  auser  auser  system_u:object_r:user_home_t    \
  index.html

5.1.4. Make Backups or Archives That Retain Security Contexts

The tar utility does not yet support archiving and restoring extended attributes in Red Hat Enterprise Linux 4. Instead, you can do this using the star utility, with the appropriate options -xattr and -H=exustar. This ensures that extra attributes are captured and the header for the *.star file is of a type that fully supports xattrs:

# Note how the two directories have different labels.
# The ellipses '...' cover the unimportant part of the
# file context for printing purposes:

ls -Z public_html/ web_files/
public_html/:
-rw-rw-r--  auser  auser  ...httpd_user_content_t 1.html
-rw-rw-r--  auser  auser  ...httpd_user_content_t 2.html
-rw-rw-r--  auser  auser  ...httpd_user_content_t 3.html
-rw-rw-r--  auser  auser  ...httpd_user_content_t 4.html
-rw-rw-r--  auser  auser  ...httpd_user_content_t 5.html
-rw-rw-r--  auser  auser  ...httpd_user_content_t index.html

web_files/:
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  1.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  2.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  3.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  4.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  5.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  index.html

star -xattr -H=exustar -c -f all_web.star public_html/ web_files/
star: 11 blocks + 0 bytes (total of 112640 bytes = 110.00k).

ls -Z all_web.star
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t \
 all_web.star
cp all_web.star /tmp/
cd /tmp/

# Here in /tmp, if there is no specific policy to make a derivative
# temporary type, the default behavior is to acquire the tmp_t type
# for new files, such as the newly copied file all_web.star,

ls -Z all_web.star
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  all_web.star

# *.star files are usable by tar, but tar does not know how to 
# extract extended attributes.  Without a label on the file, 
# the creation of new files in /tmp again chooses the default file
# type of tmp_t:

tar -xvf all_web.star
...
ls -Z /tmp/public_html/ /tmp/web_files/
/tmp/public_html/:
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  1.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  2.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  3.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  4.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  5.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  index.html

/tmp/web_files/:
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  1.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  2.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  3.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  4.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  5.html
-rw-rw-r--  auser  auser  user_u:object_r:tmp_t  index.html

rm -rf /tmp/public_html/ /tmp/web_files/

# Now you can expand the archives using star and it 
# restores the extended attributes:

star -xattr -x -f all_web.star
star: 11 blocks + 0 bytes (total of 112640 bytes = 110.00k).
ls -Z /tmp/public_html/ /tmp/web_files/
/tmp/public_html/:
-rw-rw-r--  auser  auser  ...httpd_sys_content_t 1.html
-rw-rw-r--  auser  auser  ...httpd_sys_content_t 2.html
-rw-rw-r--  auser  auser  ...httpd_sys_content_t 3.html
-rw-rw-r--  auser  auser  ...httpd_sys_content_t 4.html
-rw-rw-r--  auser  auser  ...httpd_sys_content_t 5.html
-rw-rw-r--  auser  auser  ...httpd_sys_content_t index.html

/tmp/web_files/:
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  1.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  2.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  3.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  4.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  5.html
-rw-rw-r--  auser  auser  user_u:object_r:user_home_t  \
index.html

CautionCaution
 

If you use an absolute path when you create an archive using star, the archive expands on that same path. For example, an archive made with this command restores the files to /var/log/httpd/:

star -xattr -H=exustar -c -f httpd_logs.star /var/log/httpd/

If you attempt to expand this archive, star issues a warning if the files in the path are newer than the ones in the archive.