Mission Briefing
A production system is on fire. Over 200 AVC denials in the last 24 hours across multiple services. Some are legitimate policy gaps. Others are an active intrusion attempt. Triage every denial, write custom policy for a three-tier stack, and implement Multi-Level Security. Everything you have learned, all at once.
Phase 1: Triage the Audit Log
The first step is never to start writing policy. The first step is to understand what the system is telling you. Pull the full set of denials and categorize them:
[root@gamehost ~]# ausearch -m AVC -ts yesterday | audit2allow -a -w
type=AVC: 47 denials for httpd_t accessing postgresql_port_t (tcp connect)
type=AVC: 12 denials for httpd_t accessing redis_port_t (tcp connect)
type=AVC: 89 denials for httpd_t accessing var_log_t (write)
type=AVC: 3 denials for unconfined_t accessing shadow_t (read)
type=AVC: 15 denials for container_t accessing etc_t (write)
type=AVC: 41 denials for httpd_t accessing user_home_t (read)
The -w flag explains each denial in plain text. But explanation is not justification. Look critically:
- httpd connecting to PostgreSQL and Redis - Likely legitimate. Solvable with booleans or custom policy.
- httpd writing to var_log_t - Suspicious. Apache should write to
httpd_log_t, not generic var_log_t. Misconfigured log path or labels.
- unconfined_t reading shadow_t - Alarming. Could be legitimate (passwd, sudo) or an attacker. Check the PID and comm field.
- container_t writing to etc_t - Active attack indicator. No legitimate container writes to host
/etc. Container escape attempt.
Phase 2: Policy for a Three-Tier Stack
Nginx (reverse proxy), a Python application server, and PostgreSQL - each needs its own SELinux domain. Start with the application server, which has no stock policy:
policy_module(appserver, 1.0.0)
type appserver_t;
type appserver_exec_t;
type appserver_data_t;
type appserver_log_t;
type appserver_tmp_t;
init_daemon_domain(appserver_t, appserver_exec_t)
logging_log_file(appserver_log_t)
files_tmp_file(appserver_tmp_t)
allow appserver_t appserver_data_t:file { read open getattr };
allow appserver_t appserver_data_t:dir { search getattr open read };
allow appserver_t appserver_log_t:file { create write append open getattr };
allow appserver_t appserver_tmp_t:file { create read write unlink open };
corenet_tcp_bind_http_port(appserver_t)
corenet_tcp_connect_postgresql_port(appserver_t)
postgresql_stream_connect(appserver_t)
Then define inter-domain rules. Nginx connects to the app server. The app server connects to PostgreSQL. But Nginx cannot reach PostgreSQL directly. Even if Nginx is compromised, the attacker cannot query the database.
Phase 3: Multi-Level Security
MLS adds sensitivity levels and categories to every subject and object. Where targeted policy asks "what type is this?", MLS asks "what classification level is this data, and does this process have clearance?"
MLS uses range notation: s0-s3:c0.c1023. Sensitivity levels (s0 through s15) form a strict hierarchy - a process at s2 can read s0-s2 but not s3. This is the Bell-LaPadula model: "no read up, no write down."
[root@gamehost ~]# semanage login -a -s staff_u -r s0-s2:c0.c256 analyst_user
[root@gamehost ~]# chcon -l s2:c100 /opt/classified/report.pdf
[root@gamehost ~]# runcon -l s1 -t staff_t -- cat /opt/classified/report.pdf
cat: /opt/classified/report.pdf: Permission denied
The process at s1 cannot read a file at s2. No sudo, no chmod, no chown can override it. The kernel enforces clearance regardless of DAC permissions.
Switching from targeted to MLS requires a full filesystem relabel:
[root@gamehost ~]# vi /etc/selinux/config
[root@gamehost ~]# fixfiles -F relabel
[root@gamehost ~]# reboot
Challenge: The Final Gauntlet
Your system has the following problems. Solve all of them.
- Triage: Review the 200+ AVC denials. Classify each as a legitimate policy gap, a misconfiguration, or an attack indicator. Write policy only for the legitimate gaps.
- Custom policy: Write and load a complete policy module for the Python application server. It must bind port 8080, connect to PostgreSQL on 5432, read data from
/opt/app/data/, write logs to /var/log/appserver/, and create temp files in /tmp/appserver/.
- Inter-domain isolation: Ensure that Nginx can connect to the app server, the app server can connect to PostgreSQL, but Nginx cannot connect directly to PostgreSQL.
- MLS implementation: Classify the database backup files at sensitivity s2. Ensure that the web-facing processes (running at s0) cannot access them even if an attacker gains code execution through the web application.
Bonus objective: Write an incident report for the container escape attempt you found in Phase 1, including the timeline reconstructed from audit logs and the exact policy rules that prevented data exfiltration.
XP Summary
If you have completed every level and every bonus objective, here is your total:
Level 1: Enforcing Mode .............. 100 XP
Level 2: Contexts and Labels ......... 150 XP
Level 3: Custom Policy Modules ....... 200 XP
Level 4: Booleans Deep Dive .......... 200 XP
Level 5: Container Security .......... 300 XP
Level 6: The Boss Level .............. 500 XP
-----------------------------------------
TOTAL ................................ 1450 XP
ACHIEVEMENT UNLOCKED
SELinux Master
You have conquered every level of the SELinux Game. You can triage AVC denials, write custom policy, configure booleans, secure containers, and implement MLS. There is nothing left to fear from enforcing mode. +500 XP - Total: 1450 XP
Return to All Levels or read the Advanced Guides.