Skip to content
daniel@cosenza:~/blog
LinuxFix July 6, 2026 2 min read

Fixing SELinux Denials Blocking a Legitimate Service

A service that works fine with SELinux disabled fails mysteriously with it enforcing. Here's how to read audit.log, generate a targeted policy module, and fix the actual denial instead of disabling protection.

A service failing only under SELinux enforcing mode, with no obvious application-level error, is almost always a policy denial — the fix is identifying exactly what was denied and granting precisely that, not disabling SELinux.

Step 1: confirm SELinux is actually the cause

setenforce 0
# retest the failing operation
setenforce 1

If the problem disappears in permissive mode and returns in enforcing mode, SELinux is confirmed as the cause — this is a diagnostic step, not a fix; leaving SELinux permissive/disabled removes real protection rather than solving the underlying policy gap.

Step 2: find the specific denial in the audit log

ausearch -m avc -ts recent

This shows the exact denial: which process, which file or port, and which specific permission (read, write, name_connect) was refused.

Step 3: get a human-readable explanation

sealert -a /var/log/audit/audit.log

sealert (from setroubleshoot) translates raw AVC denials into a plain-language description and, frequently, a suggested fix.

Step 4: check if the fix is simply a mislabeled file

ls -Z /path/to/file
restorecon -v /path/to/file

A very common cause: a file moved or created outside its expected context has the wrong SELinux label — restorecon resets it to the policy-defined default for its location, which resolves a large fraction of denials without any policy changes at all.

Step 5: check if a boolean already exists for this exact scenario

getsebool -a | grep -i httpd
setsebool -P httpd_can_network_connect on

SELinux ships many pre-defined booleans for common scenarios (a web server making outbound connections, for instance) — checking for an existing boolean before writing custom policy is almost always the simpler, better-supported fix.

Step 6: generate a custom policy module for a genuinely novel denial

ausearch -m avc -ts recent | audit2allow -M mymodule
semodule -i mymodule.pp

audit2allow builds a minimal policy module granting exactly the permissions that were actually denied and logged — narrowly scoped to the specific denial, not a blanket exception.

Step 7: verify the fix resolved it without introducing new denials

ausearch -m avc -ts recent

Retest the original operation and confirm no new denials appear — a policy module that’s too broad can mask a further, more serious problem it happens to also permit.

Why disabling SELinux is never the right fix

Setting SELinux to permissive or disabled removes mandatory access control system-wide, not just for the one denial you’re troubleshooting — exactly the protection layer covered in the SELinux/AppArmor deep-dive that limits what a compromised process can do even with correct discretionary permissions. restorecon, existing booleans, and targeted audit2allow modules address the actual reported denial with much smaller, well-understood scope, which is why they’re the right tools reached for first.