Introduction to SELinux file contexts

June 05, 2021

SELinux file contexts are the most important configuration that a system administrator will have to work with when working with SELinux on the system. Contexts for files are generally identified through a label that is assigned to the file. Mislabeled files are a constant source of headaches for sysadmins, and most common SELinux issues are resolved by correcting the SELinux context.

Knowing where and how SELinux contexts are used is key to understanding and resolving SELinux related issues. The following diagram shows how contexts are applied on regular Linux resources, and how the LSM subsystem uses these contexts for decision making:

selinux files

Let’s consider a web-based deployment as an example: DokuWiki. This is a popular PHP wiki that uses files rather than a database as its backend system, and is easy to install and manage. As a web hosting platform, we will use nginx.

Getting context information

Let’s assume that the DokuWiki application will be hosted at /srv/web/localhost/htdocs/dokuwiki and that it will store its wiki pages (user content) in the data/ subdirectory. We start by downloading the latest DokuWiki tarball from the project site, http://download.dokuwiki.org, and extract it to this location:

# mkdir -p /srv/web/localhost/htdocs/
# tar -C /srv/web/localhost/htdocs/ -xvf dokuwiki.tgz
# chown -R nginx:nginx /srv/web/localhost/htdocs/dokuwiki

While distributions might have prepackaged DokuWiki installations available, we will use the manual installation approach to show the various file context-related actions in this chapter.

The contexts of files can easily be acquired using the -Z option of the ls command. Most utilities that can provide feedback on contexts will try to do so using the -Z option.

Let’s look at the current context of the dokuwiki directory itself:

# ls -dZ /srv/web/localhost/htdocs/dokuwiki
undefined_u:object_r:var_t:s0 /srv/web/localhost/htdocs/dokuwiki

The context displayed here is var_t. In the Keeping or ignoring contexts section, we will change this to the correct context (as var_t is too generic and not meant for hosting web content).

File and directory contexts are stored in the filesystem as extended attributes when the filesystem supports this. An extended attribute (often abbreviated to xattr) is a key/value combination associated with a resource’s inode (an information block that represents a file, directory, or symbolic link on a filesystem). Each resource can have multiple extended attributes, but only one value per unique key. When we talk about assigning a label to a file or directory (or relabeling a file), then we imply setting or updating this extended attribute, as it is the label that SELinux will use to obtain the SELinux context for the file.

By convention, extended attributes on Linux use the following syntax:

<namespace>.<attribute>=<value>

The namespace of an extended attribute allows for additional access controls or features. Of the currently supported extended attribute namespaces (security, system, trusted, and user), the security namespace enforces specific restrictions on manipulating the attribute: if no security module is loaded (for instance, SELinux is not enabled), then only processes with the CAP_SYS_ADMIN capability (basically root or similarly privileged processes) can modify this parameter.

We can query the existing extended attributes using the getfattr application, as shown in the following example:

$ getfattr -m . -d dokuwiki
# file: dokuwiki
security.selinux="unconfined_u:object_r:var_t:s0"

As we can see, the security.selinux extended attribute hosts the SELinux context. This ensures that non-administrative users cannot alter the SELinux context of a file when SELinux is disabled and that the SELinux policy controls who can manipulate contexts when SELinux is enabled.

The stat application can also be used to show SELinux contexts:

$ stat dokuwiki
 File: dokuwiki
 Size: 211		Blocks: 0		IO Block: 4096	
directory
Device: fd01h/64769d	Inode: 8512888	Links: 8
Access: (0755/drwxr-xr-x)	Uid: (	0/	root) Gid: (	0/	root)
Context: unconfined_u:object_r:var_t:s0
...

Getting context information from a file or directory should be as common to an administrator as getting regular access control information (the read (r), write (w), and execute (x) flags).

Interpreting SELinux context types

After using SELinux for a while, the motive behind using file labels to assign an SELinux context to the file becomes somewhat clearer. SELinux contexts are named after their purpose, allowing administrators to more easily see whether a context is correctly assigned.

Consider the context of a user file in its home directory (user_home_t), a directory in /tmp for a Java application (java_tmp_t), or a socket of rpcbind (rpcbind_var_run_t). All these files or directories have considerably different purposes on the filesystem, and this reflects itself in the assigned contexts.

Policy writers will always try to name the context consistently, making it easier for us to understand the purpose of the file, but also to make the policy almost self-explanatory so that administrators can understand the purpose of the policy without additional documentation needs.

For the regular filesystem, for instance, files are labeled with a context resembling their main location as they have similar security properties. For example, we find binaries in the /bin folder (and /usr/bin) to be associated with the bin_t type, boot files in /boot associated with boot_t, and generic system resources in /usr associated with usr_t.

We can also find more application-specific contexts. For instance, for the PostgreSQL database server, we have the following:

  • The postgresql_t context is meant for the application itself (process type or domain).
  • The postgresql_port_t context is meant for the TCP port on which the PostgreSQL daemon listens.
  • The postgresql_server_packet_t and postgresql_client_packet_t contexts are types associated with network packets received (in case of the postgresql_server_packet_t type) or sent to the PostgreSQL port.
  • The postgresql_exec_t type is assigned to the postgres binary.
  • The various postgresql_*_t types for specific filesystem locations related to the daemon, such as postgresql_var_run_t (to apply to resources in /var/run), postgresql_etc_t (to apply to resources in /etc), postgresql_log_t (to apply to resources in /var/log), and postgresql_tmp_t (to apply to resources in /tmp).
  • The mysqld_db_t type for the database files themselves.

Based on the context of a file or resource, administrators can easily detect anomalies in the system setup. An example of an anomaly is when we move a file from the user’s home directory to a web server location. When this occurs, the file retains the user_home_t context as extended attributes are moved with it. As the web server process isn’t allowed to access user_home_t by default, it will not be able to serve this file to its users.

Let’s see how to properly set contexts during such copy or move operations.

Related Articles

No Results Found

The page you requested could not be found. Try refining your search, or use the navigation above to locate the post.

Lorem ipsum dolor sit amet consectetur

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

sixteen + fourteen =