Level 2

Contexts and Labels

Difficulty: Beginner | Reward: +150 XP | Prerequisites: Level 1

Mission Briefing

A developer moved a web application to a new directory using mv instead of cp. The files kept their original security labels, and now Apache cannot serve them. You need to understand how SELinux labels work, diagnose the mislabeled files, and restore them to the correct context.

The Security Context Format

Every file, process, port, and user on an SELinux-enabled system has a security context. The context is a string with four fields separated by colons:

user:role:type:level

User is the SELinux user identity. This is not the same as a Linux user account. Common SELinux users include system_u (for system processes and files), unconfined_u (for users in the unconfined domain), and staff_u (for staff users with limited admin access).

Role determines which domains (types) a user can enter. Processes run in roles like system_r (system daemons) or unconfined_r (unrestricted users). Files always have the object_r role because files do not execute code - they are passive objects.

Type is the most important field in the targeted policy. Type enforcement is the core mechanism that controls access. When you see an AVC denial, the scontext type (the process) was denied access to the tcontext type (the resource). Almost all troubleshooting on a targeted policy system comes down to getting the types right.

Level is used by Multi-Level Security (MLS) and Multi-Category Security (MCS). On a standard targeted policy, you will usually see s0 here. MCS becomes important when you reach Level 5 and work with containers.

Inspecting Labels on Files

The -Z flag on ls shows the security context alongside the normal file listing:

[root@gamehost ~]# ls -Z /var/www/html/
system_u:object_r:httpd_sys_content_t:s0 index.html
system_u:object_r:httpd_sys_content_t:s0 style.css
system_u:object_r:httpd_sys_content_t:s0 app.js

These files are labeled httpd_sys_content_t, which the policy allows httpd_t (the Apache process) to read. This is how type enforcement works: the process type and the file type must match according to the policy rules.

Now compare that to files that were moved from a home directory:

[root@gamehost ~]# ls -Z /srv/webapp/public/
unconfined_u:object_r:user_home_t:s0 index.html
unconfined_u:object_r:user_home_t:s0 style.css
unconfined_u:object_r:user_home_t:s0 app.js

These files have the user_home_t type. The httpd policy does not allow httpd_t to read user_home_t files. This is exactly the kind of problem you saw at the end of Level 1.

Inspecting Labels on Processes

Use ps -Z to see what context a running process has:

[root@gamehost ~]# ps -eZ | grep httpd
system_u:system_r:httpd_t:s0 1234 ? 00:00:02 httpd
system_u:system_r:httpd_t:s0 1235 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 1236 ? 00:00:00 httpd

The httpd workers run as httpd_t. The targeted policy defines exactly what httpd_t can access: files labeled httpd_sys_content_t (read), httpd_sys_rw_content_t (read-write), ports in the http_port_t set, and so on.

Inspecting Your Own Context

The id -Z command shows your current security context:

[root@gamehost ~]# id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

If you are logged in as root on a default targeted system, you are typically in the unconfined_t domain. This means SELinux does not restrict your actions. Confined processes like httpd are the ones that get type enforcement applied to them.

How Labels Get Assigned

When a file is created, it inherits a label based on the parent directory's context and the file context rules in the policy. The command semanage fcontext -l lists all the rules:

[root@gamehost ~]# semanage fcontext -l | grep /var/www
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
/var/www/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0

This tells you that anything under /var/www should be labeled httpd_sys_content_t. When you use cp to copy a file into /var/www, the new file gets the correct label automatically. But when you use mv, the file keeps its original label. This is one of the most common sources of SELinux issues.

Fixing Labels with restorecon

The restorecon command resets file labels to the values defined in the policy:

[root@gamehost ~]# restorecon -Rv /srv/webapp/public/
Relabeled /srv/webapp/public/index.html from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:httpd_sys_content_t:s0
Relabeled /srv/webapp/public/style.css from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:httpd_sys_content_t:s0
Relabeled /srv/webapp/public/app.js from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:httpd_sys_content_t:s0

The -R flag makes it recursive. The -v flag prints what it changed. For this to work, there must be a file context rule that covers the path. If your web root is at a non-standard location like /srv/webapp, you may need to add a rule first:

[root@gamehost ~]# semanage fcontext -a -t httpd_sys_content_t "/srv/webapp(/.*)?"
[root@gamehost ~]# restorecon -Rv /srv/webapp/

The semanage fcontext -a command adds a new rule. The regex pattern /srv/webapp(/.*)? matches the directory itself and everything inside it. After adding the rule, restorecon applies it.

Temporary Label Changes with chcon

The chcon command changes a file's context immediately, but the change is temporary. Running restorecon or relabeling the filesystem will overwrite it:

[root@gamehost ~]# chcon -t httpd_sys_content_t /srv/webapp/public/index.html

Use chcon for quick testing. Use semanage fcontext plus restorecon for permanent fixes. If you rely on chcon in production, a filesystem relabel will undo your work.

Challenge: The Mislabeled Web Directory

A junior admin created a new document root at /opt/sites/corporate by running mv ~/website/* /opt/sites/corporate/. Apache returns 403 errors for every request.

Your tasks:

  1. Run ls -Z /opt/sites/corporate/ to see the current labels
  2. Identify the incorrect type (it will be user_home_t or similar)
  3. Add a file context rule for /opt/sites/corporate using semanage fcontext
  4. Apply the rule with restorecon -Rv
  5. Verify the labels changed with ls -Z
  6. Confirm Apache can now serve the files

Bonus objective: The site also has a writable upload directory at /opt/sites/corporate/uploads. What type should it have? (Hint: it is not httpd_sys_content_t.)

Key Commands Reference

# Inspect labels
$ ls -Z /path/to/files
$ ps -eZ | grep processname
$ id -Z

# List file context rules
$ semanage fcontext -l | grep /path

# Add a permanent file context rule
# semanage fcontext -a -t httpd_sys_content_t "/path(/.*)?"

# Apply rules to files
# restorecon -Rv /path/

# Temporary label change (testing only)
# chcon -t type_t /path/to/file
ACHIEVEMENT UNLOCKED

Label Detective

You can read, diagnose, and fix SELinux security contexts on files and processes. +150 XP

Next: Level 3 - Custom Policy Modules