Rocky Linux SELinux Enforcing Mode: Boundaries, Checks, and Failure Modes
Rocky Linux enables SELinux in enforcing mode by default to maintain RHEL binary compatibility and a hardened security posture. This architecture note covers the minimal design, trust boundaries, operational checks, and failure modes—plus how to fix a mislabeled web root instead of disabling MAC.
08 Oct 2025, 04:01 UTC

The Problem: Disabling SELinux to "Fix" Services
Many administrators respond to a service failure by setting SELinux to permissive or disabling it entirely. On Rocky Linux 8 and 9, this removes the mandatory access control (MAC) layer that the distribution enables by default to maintain binary compatibility with RHEL and provide a hardened out-of-the-box posture. The useful takeaway: treat enforcing mode as part of the platform contract, and resolve denials by correcting file labels or policy rather than turning the control off.
Requirements and the Default Posture
Rocky Linux must preserve RHEL binary compatibility while shipping a secure baseline. The project satisfies both requirements by enabling SELinux in enforcing mode during installation and first boot. This is not an optional add-on; it is part of the base system design. The default policy type is targeted, which confines key network and system services while leaving most user-space processes unconfined.
The Smallest Suitable Design
The minimal implementation relies on components already present in a standard install:
- The system boots with SELinux enabled in enforcing mode, and the choice is persisted in
/etc/selinux/config. - The
selinux-policy-targetedRPM provides the loaded policy modules and file-context definitions. - The audit subsystem records access denials for operational review.
No additional packages are required. The design is intentionally small: one policy type, one config file, and audit visibility.
Trust and Data Boundaries
SELinux implements MAC by assigning security contexts to processes and files. Unlike traditional Unix permissions, where access is governed by user and group ownership, SELinux decisions are made by the kernel using type enforcement. A process running in a domain (for example, httpd_t) can only interact with resources labeled with compatible types (for example, httpd_sys_content_t). This creates hard boundaries between system services and user data, limiting the blast radius of a compromised process.
For example, if an attacker exploits a vulnerability in a web server, the httpd_t domain cannot read files labeled var_log_t or execute binaries in user home directories unless policy explicitly allows it. These boundaries are the architectural value of the default enforcing mode.
Operational Checks
Verify the mode immediately after installation and after any kernel or policy update.
Confirm Enforcing Mode
Run as root or with sudo on the Rocky Linux host:
getenforce
Expected output: Enforcing. If the output is Permissive or Disabled, the system is not operating with the intended MAC controls.
Inspect Policy and Boot Configuration
Run:
sestatus
Look for SELinux status: enabled, Current mode: enforcing, and Mode from config file: enforcing. Also confirm the policy version and the loaded policy name (targeted).
Check the persistent configuration:
grep -E '^SELINUX=' /etc/selinux/config
Expected: SELINUX=enforcing and SELINUXTYPE=targeted. If the kernel command line was modified, verify with:
cat /proc/cmdline
Review Denials
When a service behaves unexpectedly, inspect the audit log before changing modes. Run as root:
ausearch -m avc -ts recent
Or use sealert if the setroubleshoot-server package is installed to translate raw denials into human-readable suggestions. Denials are recorded in /var/log/audit/audit.log.
A Concrete Example: Serving Web Content from a Custom Path
Suppose you deploy a static site under /opt/webroot instead of /var/www/html. Apache will fail to serve files because the directory inherits a default label rather than httpd_sys_content_t. The denial appears in the audit log, but the service may simply return 403 errors.
Do not set the system to permissive. Instead, apply the correct context. As root, run:
semanage fcontext -a -t httpd_sys_content_t "/opt/webroot(/.*)?" restorecon -Rv /opt/webroot
The first command registers the new path mapping in policy; the second applies it recursively. Afterward, restart the service and confirm it responds. If the path is temporary, chcon can set the label directly, but semanage survives a full filesystem relabel.
Failure Modes
- Permissive drift: An administrator sets
SELINUX=permissiveto debug an issue and forgets to revert. The system logs denials but does not block them, silently removing MAC. - Disabled at boot: Editing the kernel command line to include
selinux=0prevents SELinux from initializing. This is the most severe failure mode because the system cannot return to enforcing without a reboot and config repair. - Mislabeled files: Copying content with
cp -aor extracting archives can preserve incorrect labels, causing services to fail after a migration or deployment. - Policy mismatch: Loading a custom policy compiled for a different SELinux version can prevent the system from booting if the policy is invalid.
Conditions That Would Change the Design
The default enforcing posture is appropriate for general-purpose Rocky Linux servers. Revisit it only under specific conditions:
- Container-only workloads where the container runtime provides the primary isolation boundary and host SELinux is used to confine the runtime itself rather than individual host services.
- Adoption of a different MAC framework, such as AppArmor, which would require removing or disabling
selinux-policy-targetedand ensuring the alternative framework is fully enforced. - Specialized appliances where the supported software stack has documented incompatibilities with targeted policy and the vendor provides a signed, tested alternative policy.
Limitations and Practical Verification
SELinux targeted policy does not confine every process; many user-space applications run in unconfined domains. It also does not replace discretionary access control, network firewalls, or application-level authentication. Custom policy changes must be tested in a non-production environment because incorrect type enforcement rules can block essential services or prevent boot.
To verify the system is operating as designed after any change, run getenforce and sestatus again, then confirm that expected services start without new AVC denials in the audit log. If denials appear, fix the label or adjust policy with audit2allow only after human review, rather than blanket-allowing the service.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.