Community Tutorials RHEL / Rocky / AlmaLinux How to Set SELinux to Permissive Mode for Debugging
How to Set SELinux to Permissive Mode for Debugging
RHEL / ROCKY / ALMALINUX

How to Set SELinux to Permissive Mode for Debugging

SKYLINE Knowledge Base
Photo by imattsmart on Unsplash

A field-tested, step-by-step guide. How to Set SELinux to Permissive Mode for Debugging — prerequisites, the actual commands, verification, and links to related RHEL / Rocky / AlmaLinux topics.

SELinux on RHEL family is excellent — and it is the first thing many operators reach to disable when an app misbehaves. Don't. Permissive mode logs would-be denials without enforcing them, which lets you debug without losing the safety net.

Prerequisites

  • Rocky 9 / Alma 9 / RHEL 9 with sudo.
  • A service or app that "works on the dev box and breaks on the RHEL server."

Step 1: Confirm current SELinux state

sestatus
getenforce        # Enforcing | Permissive | Disabled

Three modes:

  • Enforcing — default. Blocks anything not allowed by policy.
  • Permissivelogs denials but allows the operation. Ideal for debugging.
  • Disabled — turns SELinux off entirely. Only as a last resort.

Step 2: Switch to permissive — runtime only

sudo setenforce 0
getenforce        # Permissive

This is non-persistent. A reboot puts it back to Enforcing. Use this while you reproduce the bug.

Step 3: Look at the denials

sudo grep -i 'avc:.*denied' /var/log/audit/audit.log | tail -30
sudo ausearch -m AVC -ts recent | tail
sudo journalctl _TRANSPORT=audit -p err -n 50

Better, use sealert (from setroubleshoot-server):

sudo dnf install -y setroubleshoot-server
sudo sealert -a /var/log/audit/audit.log | less

sealert summarises each denial AND prints the exact semanage / chcon / audit2allow command to allow it.

Step 4: Fix the policy properly

The typical resolutions:

Wrong file label — most common:

sudo ls -lZ /var/www/html/missing-page.html
sudo restorecon -Rv /var/www/html

Custom directory outside the standard tree:

sudo semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web

Custom port for a known service:

sudo semanage port -a -t http_port_t -p tcp 8081

Real policy gap — use audit2allow to generate a module:

sudo ausearch -m AVC -ts recent | audit2allow -M skyline-myapp
sudo semodule -i skyline-myapp.pp

Inspect the generated .te file before loading — audit2allow is happy to write a too-permissive policy.

Step 5: Switch back to enforcing

sudo setenforce 1
getenforce        # Enforcing

If you must make permissive persist across reboot (e.g., for an extended outage), edit /etc/selinux/config:

SELINUX=permissive

SELINUX=disabled is strongly discouraged — it skips relabelling on next boot and is hard to recover from cleanly.

Verify

sestatus
sudo ausearch -m AVC -ts today | wc -l
sudo grep "denied" /var/log/audit/audit.log | wc -l

After your fix, denials should drop to zero.

Conclusion

SELinux is a friend, not an obstacle. Use permissive + sealert + audit2allow to learn what your app actually needs, ship a tiny policy module, and stay enforcing. Five minutes of policy work beats a year of "we just turn it off."

Next steps

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship RHEL / Rocky / AlmaLinux for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.