Solution¶
Triage¶
- Check SELinux status:
- Check audit log for denials:
- Check file contexts:
- Translate the denial:
Root Cause¶
The binary /opt/inventory-api/bin/server was deployed by copying files to /opt/inventory-api/. Files in /opt inherit the SELinux context usr_t by default, not bin_t. When the systemd service tries to execute the binary, SELinux denies the execution because the init_t domain (systemd) is not allowed to execute files labeled usr_t.
Additionally, the application tries to:
1. Bind to port 9090, which is not in the default http_port_t SELinux type.
2. Read configuration from /opt/inventory-api/config/, which has the usr_t context.
All three denials must be resolved for the service to start.
Fix¶
-
Set the correct file context for the binary:
-
Set the correct context for config and data directories:
-
Allow the service to bind to port 9090:
-
If additional denials exist, generate a custom policy module:
# Collect all denials in permissive mode first: semanage permissive -a init_t systemctl start inventory-api # Let it run for a few minutes to collect all denials ausearch -m AVC -ts recent | audit2allow -M inventory-api semodule -i inventory-api.pp # Remove permissive exception: semanage permissive -d init_t -
Start the service:
Rollback / Safety¶
- File context changes are persistent and survive reboots.
- If the custom policy module causes issues, remove it:
semodule -r inventory-api. - To test without committing, use permissive mode for the specific domain rather than the entire system.
- Keep SELinux in enforcing mode. Never disable it permanently in production.
Common Traps¶
- Disabling SELinux as the fix. This is the most common and worst response. SELinux is a critical security control.
- Using
chconinstead ofsemanage fcontext+restorecon.chconchanges are temporary and lost whenrestoreconis run or during filesystem relabel. - Running
audit2allowblindly.audit2allowmay generate overly permissive policies. Always review the generated policy before installing. - Not collecting all denials. Fix one denial, restart, hit another denial, repeat. Use permissive mode for the domain to collect ALL denials at once.
- Forgetting
restoreconaftersemanage fcontext.semanage fcontextupdates the policy database but does not change file labels on disk.restoreconapplies the policy to existing files.