SELinux
SELinux (Security-Enhanced Linux) is the default MAC system on RHEL, Fedora, and CentOS. It labels every file, process, and network port with a security context, then enforces rules about which labels can interact with which. Even if an attacker exploits a web server running as root, SELinux confines it to what httpd is allowed to do.
Security Contexts and Labels
What is a SELinux label?
Every object (file, process, socket) gets a security context: a 4-part label. Format: user:role:type:level. The type is the most important part for policy — rules say "processes of type X can perform operation Y on objects of type Z." Labels are stored as extended attributes on files (xattr) and assigned to processes at exec time.
# See process labels:
ps -Z
# LABEL PID COMMAND
# system_u:system_r:httpd_t:s0 1234 httpd
# system_u:system_r:sshd_t:s0 5678 sshd
# unconfined_u:unconfined_r:unconfined_t:s0 9012 bash
# See file labels:
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
ls -Z /etc/passwd
# system_u:object_r:passwd_file_t:s0 /etc/passwd
# Get context of a specific file:
stat -c "%C" /etc/httpd/conf/httpd.conf
# system_u:object_r:httpd_config_t:s0
Reading AVC Denial Messages
# AVC = Access Vector Cache — where SELinux logs denials
# View denials in audit log:
ausearch -m AVC -ts recent
# Example denial:
# type=AVC msg=audit(1234567890.123:456): avc: denied { read }
# for pid=1234 comm="httpd" name="secret.txt"
# dev="sda1" ino=5678
# scontext=system_u:system_r:httpd_t:s0
# tcontext=system_u:object_r:admin_home_t:s0
# tclass=file permissive=0
# Decoded:
# process: httpd (httpd_t)
# tried to: read
# the file: secret.txt
# which has type: admin_home_t
# result: DENIED (httpd_t cannot read admin_home_t files)
# Human-readable:
sealert -a /var/log/audit/audit.log
Fixing SELinux Denials
# Option 1: Fix the file label (usually correct approach)
# Wrong label on a web file:
ls -Z /var/www/html/myfile.txt
# unconfined_u:object_r:user_home_t:s0 myfile.txt ← wrong!
# Fix the label:
restorecon -v /var/www/html/myfile.txt
# Relabeled: user_home_t -> httpd_sys_content_t
# Recursively fix a directory:
restorecon -Rv /var/www/html/
# Change file type permanently:
chcon -t httpd_sys_content_t /var/www/html/myfile.txt
# Option 2: Enable a boolean (predefined policy switch)
getsebool -a | grep httpd
# httpd_can_network_connect --> off
# httpd_can_sendmail --> off
# httpd_enable_cgi --> on
# Allow httpd to connect to network (e.g., proxy to backend):
setsebool -P httpd_can_network_connect 1
# -P = persistent across reboots
# Option 3: Write a custom policy module
audit2allow -M mypolicy < /var/log/audit/audit.log
semodule -i mypolicy.pp
SELinux Modes
# Three modes:
getenforce
# Enforcing = policy enforced, denials logged
# Permissive = not enforced but denials logged (testing mode)
# Disabled = completely off (requires reboot to change)
# Switch to permissive (for debugging — useful to see what WOULD be denied):
setenforce 0 # temporary
getenforce
# Permissive
setenforce 1 # back to enforcing
# Permanent mode (/etc/selinux/config):
# SELINUX=enforcing
# SELINUXTYPE=targeted (targeted = only specific processes confined)
# Per-process permissive mode (leave rest enforcing):
semanage permissive -a httpd_t # make just httpd_t permissive
semanage permissive -l # list permissive domains
Frequently Asked Questions
What will I learn here?
This page covers the core concepts and techniques you need to understand the topic and progress confidently to the next lesson.
How should I use this page?
Start with the overview, then follow the section links to deepen your understanding. Use the table of contents on the right to jump to specific sections.
What should I read next?
Use the navigation below to continue to the next lesson or explore related topics.