Mastering AlmaLinux's strongest security layer: understanding the difference between MAC and DAC, managing enforcing, permissive, and disabled modes, reading and fixing security contexts, setting booleans, and troubleshooting blocked services via ausearch and sealert.

In the previous episode, Episode 12, we tidied up logging, time sync, and automation. Now we enter the layer that sets AlmaLinux apart from mainstream distros: SELinux. This is the Mandatory Access Control (MAC) that's active by default on AlmaLinux in enforcing mode — and one of the main reasons the RHEL ecosystem is known for security.
This episode breaks down the difference between MAC and DAC, the three SELinux modes, security context structure, booleans, and — most importantly — the troubleshooting pattern when SELinux blocks your services.
You've been familiar with DAC (Discretionary Access Control) since episode 6: rwx permissions controlled by the file owner. The name "discretionary" refers to the fact that the object's owner is free to determine access.
MAC (Mandatory Access Control) works on top of DAC. Access is determined by centralized policy based on context labels — not by the file owner's will. Two crucial differences:
An analogy: DAC is a house key the owner can copy; MAC is the building's security guard with an official list of who may enter which room — a list the room owner can't change.
| Aspect | DAC | MAC (SELinux) |
|---|---|---|
| Access decider | Object owner | Centralized policy |
| Decision basis | User and group | Context labels |
| Root | Not restricted | Restricted |
| Default principle | Open unless locked | Closed unless allowed |
SELinux has three modes you may encounter:
| Mode | Behavior |
|---|---|
| Enforcing | Policy enforced; forbidden access is blocked and logged |
| Permissive | Violations are logged but not blocked |
| Disabled | SELinux completely off |
getenforce
sestatusgetenforce shows the running mode; sestatus shows full status including the loaded policy. To switch modes without rebooting:
sudo setenforce 0
sudo setenforce 1setenforce 0 switches to permissive mode, setenforce 1 back to enforcing. This only changes the running mode — the permanent mode is controlled in /etc/selinux/config.
Danger
Never disable SELinux in /etc/selinux/config with SELINUX=disabled as a problem-solving approach. An SELinux denial is information — not an enemy. Follow the troubleshooting pattern below, not a shortcut that opens a security hole.
Every process and object in SELinux has a security context — the label that is the basis of access decisions. Its format:
user:role:type:sensitivity
system_u:object_r:httpd_sys_content_t:s0Four fields: user, role, type, and sensitivity. The one you'll deal with most is type — for processes it's called the domain. View contexts with the -Z flag:
ls -Z /var/www/html
ps -eZ | grep httpdThe most common SELinux problem: files copied or moved carry their old labels. Fix with restorecon:
sudo restorecon -Rv /var/www/html-R is recursive, -v is verbose. restorecon restores labels according to the registered fcontext rules.
For directories outside standard locations, register fcontext rules with semanage:
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
sudo restorecon -Rv /srv/wwwsemanage fcontext -a adds a label rule, then restorecon applies it. This is a mandatory pattern when putting web content in non-standard locations.
Booleans are on/off switches that change part of the policy without writing new rules — for example, allowing httpd to access the network:
getsebool -a | grep httpd
sudo setsebool -P httpd_can_network_connect onThe -P flag makes the change persistent (survives reboot). Without -P, the change only lasts until reboot — often the source of confusion when a configuration "doesn't stick".
When a service suddenly fails — usually with a mysterious permission denied in the logs — the first step: check whether SELinux is blocking it.
sudo ausearch -m avc -ts recentsudo setenforce 0
systemctl restart myappThe correct diagnosis pattern:
ausearch -m avc -ts recent.For human-friendly interpretation, install setroubleshoot, which provides sealert:
sudo dnf5 install -y setroubleshoot-server
sudo sealert -a /var/log/audit/audit.logsealert -a analyzes the entire audit log and gives step-by-step recommendations — including the exact restorecon or setsebool commands to fix the problem.
sudo aureport -a --summaryaureport -a --summary summarizes all audit events — a quick way to see recurring denial patterns.
setenforce 0 as a permanent solution. It's only temporary and is lost at reboot — fix the root cause.-P in setsebool. Without -P, boolean changes are lost at reboot.restorecon. Labels carry over — always restore labels at the new location.ausearch. Every denial is recorded; their patterns are the best diagnostic clues.In this episode 13 you've mastered SELinux and MAC: the fundamental MAC vs DAC difference, the three enforcing, permissive, and disabled modes, security context structure, label fixing with restorecon and semanage fcontext, boolean configuration, and the denial troubleshooting pattern with ausearch and sealert.
Key takeaways:
user:role:type:sensitivity — manage the type.restorecon fixes labels; semanage fcontext for custom locations.-P for persistence.With SELinux under control, you're ready to secure remote access. In the next episode, Episode 14, we'll cover SSH Hardening & Remote Access — modern sshd configuration with ed25519 keys, disabling passwords and root, Match for conditional rules, tunneling, and hardening with Fail2ban and AllowUsers. See you there!