Skip to main content
RunBook Academy

LinuxXXVIII · SELinux and AppArmorSELinux

SELinux architecture - contexts, policy, and enforcement

Advanced⏱ ~12 minsestatusgetenforcesetenforce

What you'll learn

  • Describe how SELinux labels work
  • List the SELinux policy types (targeted, MLS)
  • Use sestatus, getenforce, setenforce
  • Understand the audit logs and AVC denials

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

SELinux (Security-Enhanced Linux) is the MAC system developed by the NSA and standard on RHEL, Rocky, Alma, and Fedora. This lesson covers the architecture: labels, policy, enforcement, and the daily-use tools.

Labels

Every file, process, port, and network packet has a SELinux context (label). The context is a colon-separated tuple:

user:role:type:sensitivity:category

For most production work, the relevant fields are user, role, and type:

system_u:object_r:httpd_sys_content_t:s0
system_u:object_r:httpd_t:s0

A file’s type determines what can read it. A process’s type determines what it can do. The policy says “process type X can read file type Y” - the type enforcement rule.

Inspect labels

ls -Z file                    # file context
ps -eZ                        # process context
netstat -tlnpZ                # port context
sestatus                      # overall status

sestatus output:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)

Key fields:

  • SELinux status: enabled or disabled.
  • Loaded policy name: typically targeted.
  • Current mode: enforcing, permissive, or disabled.

Modes

ModeBehaviour
enforcingPolicy is enforced. Denials are blocked and logged.
permissivePolicy is not enforced. Denials are logged but allowed.
disabledSELinux is off. Do not use in production.

Switch to permissive for debugging:

sudo setenforce 0       # permissive
sudo setenforce 1       # enforcing

This is not persistent across reboot. To make it persistent, edit /etc/selinux/config:

SELINUX=enforcing       # or permissive or disabled
SELINUXTYPE=targeted

Policy types

  • targeted: default on RHEL. Protects specific processes (httpd, sshd, named, etc.). Most processes run unconfined.
  • MLS (Multi-Level Security): more restrictive. Used in government and high-security environments.
  • minimum: only minimal protection. For legacy compatibility.
  • custom: built from source. Rare in production.

For new deployments, targeted is the right choice.

The targeted policy in detail

The targeted policy confines specific daemons:

  • httpd_t: Apache, Nginx (when labelled).
  • sshd_t: sshd.
  • named_t: BIND.
  • postgresql_t, mysqld_t, etc.

Most user processes run unconfined_t - effectively no MAC restrictions. The targeted policy is about confining the network-facing services.

AVC denials

When SELinux denies an action, it logs an AVC (Access Vector Cache) denial:

type=AVC msg=audit(...): avc: denied { read } for comm="nginx"
  name="passwd" pid=1234 scontext=system_u:system_r:httpd_t:s0
  tcontext=system_u:object_r:etc_t:s0 tclass=file

Reading fields:

  • denied { read }: what was denied (read access).
  • comm="nginx": the process.
  • pid=1234: the process PID.
  • scontext=...httpd_t...: source context (the process).
  • tcontext=...etc_t...: target context (the file).
  • tclass=file: target class.

Use ausearch -m avc to query AVC denials:

sudo ausearch -m avc -ts recent
sudo ausearch -m avc -ts today

Booleans

SELinux booleans are tunable switches in the policy:

getsebool -a                       # list all booleans
getsebool httpd_can_network_connect # specific boolean
sudo setsebool httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect on   # persistent

Common booleans:

  • httpd_can_network_connect: allow httpd to make outbound connections.
  • httpd_read_user_content: allow httpd to read user files.
  • ssh_keysign: enable host-based SSH auth.
  • samba_enable_home_dirs: allow Samba to share home dirs.

File contexts

Files have a context. New files inherit the parent directory’s context (with some exceptions for /tmp and /var/tmp).

ls -Z /var/www/html/
# system_u:object_r:httpd_sys_content_t:s0 index.html

To restore a context:

sudo restorecon -R /var/www/html

To set a different context permanently:

sudo semanage fcontext -a -t httpd_sys_content_t '/var/www(/.*)?'
sudo restorecon -R /var/www

semanage updates the policy database; restorecon applies it.

Knowledge check

Knowledge check · 3 questions

  1. Q1. Which command shows the SELinux mode?

  2. Q2. setenforce 0 lasts only until the next reboot.

  3. Q3. Which of the following are valid SELinux tools? Select all that apply.

Passing score: 75%. Answers are checked in this browser.