SELinux & AppArmor
Mandatory Access Control (MAC)
Everything you've learned about permissions so far - owner/group/other, ACLs - is called Discretionary Access Control (DAC): the file's owner decides who can access it, and can loosen those permissions at will. Mandatory Access Control (MAC) adds an entirely separate, system-wide policy layer on top, enforced by the kernel, that the file owner cannot override no matter what chmod says - even root is constrained by it.
Scenario: A web server process gets compromised through a vulnerability and the attacker gains its privileges. Under plain DAC, if that process's normal Linux user account happens to have read access to /etc/shadow (say, through a misconfiguration), the attacker now has it too. A MAC policy can say, categorically, "the web server process - regardless of what user it's running as - is never allowed to touch `/etc/shadow," closing that door even if the DAC permissions would technically allow it.
SELinux (RHEL/Fedora)
| Command | Purpose |
|---|---|
getenforce | Current mode |
setenforce 0/1 | Permissive / Enforcing (temporary) |
sestatus | Detailed status |
ls -Z / ps -Z | Show security contexts |
restorecon -Rv /path | Reset contexts to default |
semanage fcontext | Manage context rules |
SELinux tags every file and process with a security context (visible via -Z flags) and enforces rules about which contexts may interact with which - independent of ordinary rwx permissions. Modes: Enforcing (violations are blocked), Permissive (violations are only logged, not blocked - useful for testing a new policy safely), Disabled. Configured in /etc/selinux/config.
AppArmor (Ubuntu/SUSE)
Where SELinux tags files with contexts, AppArmor takes a simpler, path-based approach: profiles describe what a specific program is allowed to do by file path, stored under /etc/apparmor.d/. Managed with aa-status, aa-enforce, aa-complain.
Warning: A very common real-world incident: a service works perfectly fine while SELinux is in permissive mode, then mysteriously breaks the moment it's switched to enforcing - with no useful error from the application itself, because SELinux blocks the action at the kernel level before the application even gets a meaningful error back. When you see a service fail in enforcing mode but not permissive, that's almost always a security-context problem, not an application bug. Check/var/log/audit/audit.logfor the actual denial record, andrestorecon(reset a file's context to its policy-defined default) oraudit2allow(generate a custom policy exception from recent denials) are the standard fixes.