HackBlue

Tools · Linux command line for security · 10 / 28

SELinux vs AppArmor: what they do and how to read a denial

Understand mandatory access control, check whether SELinux or AppArmor is enforcing, read a denial in the audit log, and fix it without disabling protection.

11 min read · practice only with authorization

Mandatory access control

Standard permissions let a process do anything its user can. Mandatory access control adds a policy that limits what a specific program can touch, even when running as root. If a compromised web server tries to read /etc/shadow or open an outbound connection, the policy can block it.

SELinux, the default on RHEL, Fedora, and their relatives, labels every file and process with a type and allows only listed interactions. AppArmor, the default on Ubuntu and SUSE, uses path-based profiles per program. Both have an enforcing mode and a permissive or complain mode that logs without blocking.

Check the current state

getenforce prints Enforcing, Permissive, or Disabled. sestatus gives detail. ls -Z and ps -Z show labels. On Ubuntu, sudo aa-status lists loaded profiles and which processes are confined in enforce or complain mode.

A common anti-pattern is “setenforce 0” in a setup guide. It turns off a strong protection to make one app work. Fixing the label or profile is usually a one-line change.

Snippet
getenforce; sestatus
ls -Z /var/www/html
ps -eZ | grep httpd
sudo aa-status

Lab: cause and fix a denial

On a Fedora or RHEL lab VM with Apache, create a page in /srv/site and point DocumentRoot at it. The browser gets a 403 because the files carry the default_t label. ausearch -m avc -ts recent shows the denial, and audit2why explains it. Fix it by labeling the path with semanage fcontext and restorecon, then reload.

On Ubuntu, set a profile to complain mode with aa-complain, exercise the app, and use aa-logprof to propose rules from the logged events. Return it to enforce with aa-enforce.

Snippet
sudo ausearch -m avc -ts recent | audit2why
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/site(/.*)?"
sudo restorecon -Rv /srv/site

# Ubuntu
sudo aa-complain /usr/sbin/nginx
sudo aa-logprof
sudo aa-enforce /usr/sbin/nginx

Why keep it on

Many real exploits succeed at getting code running in a web server but then fail to go further because the policy blocked a file read or a network connection. Those denials are also excellent detection signals, so forward AVC and AppArmor DENIED messages to your log platform.

Booleans make common changes easy on SELinux, for example setsebool -P httpd_can_network_connect on for a reverse proxy.

Diagram

Two ways to fix an SELinux 403

The fast fix and the right fix.

Turn it off

Command. setenforce 0

Effect. Every confined service loses protection.

Result. Problem hidden, risk increased.

Fix the label

Command. semanage fcontext + restorecon

Effect. Only the new path gets web content type.

Result. Site works, policy still enforced.

Check yourself

1. Which command shows whether SELinux is enforcing?

2. How does AppArmor mainly identify what a profile covers?

3. Apache gets 403 on new files in /srv/site under SELinux. What is the right fix?