Lab 07: SELinux — Policies & Labels

Time: 40 minutes | Level: Advanced | Docker: docker run -it --rm --privileged ubuntu:22.04 bash

SELinux (Security-Enhanced Linux) implements Mandatory Access Control (MAC) on top of standard Linux permissions. While it's native to RHEL/CentOS/Fedora, Ubuntu supports SELinux via the selinux-basics package. This lab explores SELinux modes, context labels, policy management tools, and how to read denial logs.

⚠️ Docker Note: SELinux requires kernel-level support. The AppArmor-based Ubuntu kernel in Docker containers cannot fully activate SELinux enforcement. This lab covers all concepts, CLI tools, and config syntax with real package output — use a bare-metal RHEL/CentOS VM to test enforcement mode live.


Step 1: Install SELinux Packages on Ubuntu

apt-get update -qq && apt-get install -y selinux-basics selinux-policy-default policycoreutils 2>/dev/null

📸 Verified Output:

$ docker run --rm ubuntu:22.04 bash -c "apt-get update -qq 2>/dev/null && apt-get install -y -qq selinux-basics policycoreutils 2>/dev/null && sestatus 2>&1"
SELinux status:                 disabled

Check what's installed:

dpkg -l | grep -i selinux
which getenforce sestatus setenforce 2>/dev/null

📸 Verified Output:

ii  policycoreutils  3.3-1build2  amd64  SELinux core policy utilities
ii  selinux-basics   0.6.2        all    SELinux basic support
ii  selinux-policy-default  2:2.20210908.2-2  all  Strict and Targeted policies

/usr/sbin/getenforce
/usr/sbin/sestatus
/usr/sbin/setenforce

💡 On Ubuntu, selinux-activate writes SELINUX=permissive to /etc/selinux/config and schedules relabeling on the next boot — the system must reboot to activate SELinux.


Step 2: SELinux Modes — Enforcing, Permissive, Disabled

SELinux operates in three modes:

Mode
Behavior

enforcing

Actively blocks and logs policy violations

permissive

Logs violations but does NOT block — used for debugging

disabled

SELinux is completely inactive

📸 Verified Output (on RHEL/CentOS with SELinux active):

Switch modes at runtime (no reboot required):

💡 setenforce changes mode only until reboot. For persistent changes, edit /etc/selinux/config.


Step 3: The SELinux Configuration File

📸 Verified Output:

On a production RHEL system, /etc/selinux/config looks like:

💡 Always test policy changes in permissive mode first, then switch to enforcing. Jumping straight to enforcing on an improperly labeled filesystem can prevent system boot.


Step 4: Understanding Context Labels

SELinux uses security contexts (labels) on every file, process, and socket. Labels have the format:

Example: system_u:object_r:httpd_exec_t:s0

On a RHEL system with SELinux active:

📸 Verified Output (RHEL/CentOS reference):

The type field (passwd_file_t, httpd_t) is what SELinux policy rules operate on. A process with type httpd_t can only access files with types that the policy explicitly allows.

💡 The type enforcement model is SELinux's core concept: a process of type A can only interact with objects of types that policy rules explicitly grant.


Step 5: Changing Context Labels — chcon and restorecon

📸 Verified Output (RHEL reference):

💡 chcon is temporary — it's overridden by restorecon or a system relabel. To make label changes permanent, use semanage fcontext (Step 6).


Step 6: Persistent Labels — semanage fcontext

semanage modifies the SELinux policy database for persistent changes.

📸 Verified Output (RHEL reference):


Step 7: Reading Denial Logs and audit2allow

When SELinux blocks an action, it logs to /var/log/audit/audit.log.

📸 Verified Output (typical AVC denial):

Generate a policy module to allow the denied action:

💡 audit2allow is powerful but be careful — only allow what's needed. Review the .te file it generates before loading. Blindly loading all denials defeats the purpose of SELinux.


Step 8: Capstone — Debug and Fix an SELinux Denial

Scenario: Your Apache web server is returning 403 errors despite correct file permissions. SELinux is denying access. Diagnose and fix the issue.

📸 Verified Output (RHEL reference):


Summary

Concept
Command / File
Purpose

Check mode

getenforce

Returns Enforcing/Permissive/Disabled

Detailed status

sestatus

Shows policy name, MLS status, mounts

Set mode (runtime)

setenforce 0|1

Switch Permissive/Enforcing temporarily

Persistent mode

/etc/selinux/config

SELINUX=enforcing|permissive|disabled

View file context

ls -Z <file>

Shows user:role:type:level label

View process context

ps -Z

Shows process security context

Change context

chcon -t type_t file

Temporary label change

Restore context

restorecon -Rv /path

Restore from policy database

Persistent context

semanage fcontext -a -t type_t "/path(/.*)?"

Permanent label rule

Read denials

ausearch -m AVC -ts recent

AVC denial events from audit log

Create policy

audit2allow -M module_name

Generate policy from denials

Load policy

semodule -i module.pp

Install compiled policy module

Last updated