LFCS 143 ๐ง SELinux โ Troubleshooting
The previous chapters covered the SELinux modes, contexts, and booleans. This chapter covers the workflow for diagnosing an access denial. An application fails, the logs show a denial, and the administrator must decide whether the cause is a mislabeled file, a boolean that needs to be toggled, a port that is not permitted, or a policy rule that is missing. The LFCS exam tests the commands that reveal the denial and the sequence of fixes that the administrator should try before writing a custom policy. The critical trap is the order of the fixes. A custom policy module generated by audit2allow is the last resort, not the first. The first three checks are the file context, the boolean, and the port. If none of them resolves the denial, the custom policy is the correct final step .
Key point: The ausearch -m avc command reveals the denial. The sealert command translates the denial into a human-readable explanation. The audit2why command explains why the denial occurred. The fixes, in order, are: relabel the file with restorecon, toggle the boolean with setsebool -P, add the port with semanage port -a, and only then generate a custom policy with audit2allow. The audit2allow output must be reviewed before installation, because it grants whatever the denial requested.
Why troubleshooting requires a specific sequence
The AVC log problem. When SELinux denies an action, it logs an AVC (Access Vector Cache) message. The message is in /var/log/audit/audit.log if auditd is running, and in /var/log/messages if it is not. The ausearch -m avc command searches the audit log for the AVC messages. The -ts recent flag limits the search to the recent entries, which is the correct filter after reproducing the failure .
The interpretation problem. The raw AVC message is cryptic. It contains the source context (scontext), the target context (tcontext), the target class (tclass), and the denied permission. The sealert -a /var/log/audit/audit.log command parses the log and produces a human-readable description with a suggested fix. The audit2why command translates a single AVC message into an explanation. The sealert is the more comprehensive tool because it groups the related denials and suggests the boolean or the semanage command .
The fix-order problem. The common causes of a denial are, in order of likelihood: a mislabeled file, a boolean that is off, and a port that is not permitted. The file mislabel happens when a file is moved with mv instead of cp, or when a file is created in a directory that does not have the correct default type. The boolean happens when a service needs a capability that the policy disables by default, such as httpd_can_network_connect. The port happens when a service is configured to listen on a port that is not in the service’s port type . The custom policy is the last resort for the cases that the first three do not cover.
The per-domain permissive problem. If an application has multiple denials, the enforcing mode stops at the first one. The semanage permissive -a <domain> command puts a single domain in permissive mode, which allows the application to run while logging every denial. The administrator can exercise all the application’s features, collect the complete set of denials, and generate a single policy module. The semanage permissive -d <domain> removes the permissive mode after the policy is installed .
The trade-off. The audit2allow is powerful, but it grants whatever the denial requested. A denial that is caused by a misconfiguration, such as a wrong file path or a wrong port, is not a policy problem. Running audit2allow on that denial creates a policy rule that permits the misconfiguration instead of fixing it. The correct approach is to check the file context and the boolean first, and to use audit2allow only when the denial is a genuine missing policy rule .
a. Finding and interpreting the denial
The ausearch -m avc command is the primary tool for finding the denial. The -ts recent flag limits the search to the recent entries. The -c <command> flag filters by the command name. The -exe <path> flag filters by the executable path.
# Find recent AVC denials
sudo ausearch -m avc -ts recent
# Filter by command
sudo ausearch -m avc -c httpd -ts recent
# Filter by executable
sudo ausearch -m avc -exe /usr/sbin/httpd -ts recent
The sealert command translates the denial into a description. The -a flag reads the audit log, and the -l <id> flag shows the details for a specific alert.
# Install the setroubleshoot-server package
sudo dnf install setroubleshoot-server
# Analyze the audit log
sudo sealert -a /var/log/audit/audit.log
# Show a specific alert
sudo sealert -l <alert-id>
The audit2why command is the translator for a single denial.
# Explain the denial
sudo ausearch -m avc -ts recent | audit2why
The audit2why output shows the reason: a missing type, a missing boolean, or a constraint. The reason determines the fix.
b. The fix sequence: context, boolean, port
The first check is the file context. The ls -Z shows the context. The matchpathcon -V compares the current context to the default. The restorecon -Rv applies the default.
# Check the context
ls -Z /var/www/html/file.txt
# Compare to the default
sudo matchpathcon -V /var/www/html/file.txt
# Fix the context
sudo restorecon -Rv /var/www/html/
The second check is the boolean. The getsebool shows the current value. The semanage boolean -l shows the description. The setsebool -P changes the value persistently.
# Check the boolean
getsebool httpd_can_network_connect
# Toggle the boolean
sudo setsebool -P httpd_can_network_connect on
The third check is the port. The semanage port -l shows the port types. The semanage port -a adds the port to the type.
# Check the port type
sudo semanage port -l | grep http_port_t
# Add the port
sudo semanage port -a -t http_port_t -p tcp 9496
The semanage port -a command is the fix for a service that is configured to listen on a non-standard port. The http_port_t type is the type that the httpd_t domain is allowed to bind to. The port 9496 is not in the default list, so the bind fails. The semanage port -a adds it .
c. The custom policy as the last resort
The audit2allow command generates a policy module from the denials. The -m flag generates the Type Enforcement (TE) source. The -M flag generates the compiled module (.pp). The semodule -i installs the module.
# Generate the policy source
sudo ausearch -m avc -ts recent | audit2allow -m myapp_custom
# Review the source
cat myapp_custom.te
# Generate and compile the module
sudo ausearch -m avc -ts recent | audit2allow -M myapp_custom
# Install the module
sudo semodule -i myapp_custom.pp
The myapp_custom.te file contains the allow rules. The rule format is allow <source_type> <target_type>:<class> { <permissions> };. The rule grants the source type the permissions on the target type. The rule must be reviewed before installation. The audit2allow grants whatever the denial requested, which may be more than the application needs.
The semanage permissive -a <domain> command is the tool for collecting the complete set of denials for a multi-denial application. The domain is set to permissive, the application is exercised, the denials are collected, and the single policy module is generated.
# Set the domain to permissive
sudo semanage permissive -a httpd_t
# Exercise the application
sudo systemctl restart httpd
# Generate the policy
sudo ausearch -m avc -ts recent | audit2allow -M httpd_custom
# Install the policy
sudo semodule -i httpd_custom.pp
# Remove the permissive mode
sudo semanage permissive -d httpd_t
The semanage permissive -d removes the permissive mode. The domain returns to enforcing. The installed policy module covers the denials that were collected.
Complete Example Session
# ============================================
# PART 1: REPRODUCE THE FAILURE
# ============================================
sudo systemctl restart httpd
# Job for httpd.service failed.
# ============================================
# PART 2: FIND THE DENIAL
# ============================================
sudo ausearch -m avc -ts recent
# avc: denied { name_bind } for ... tcontext=...:http_port_t ... tclass=tcp_socket
# ============================================
# PART 3: INTERPRET WITH SEALERT
# ============================================
sudo sealert -a /var/log/audit/audit.log
# SELinux is preventing httpd from name_bind access on the tcp_socket port 9496.
# ============================================
# PART 4: CHECK THE PORT TYPE
# ============================================
sudo semanage port -l | grep http_port_t
# http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
# ============================================
# PART 5: ADD THE PORT
# ============================================
sudo semanage port -a -t http_port_t -p tcp 9496
# ============================================
# PART 6: RESTART THE SERVICE
# ============================================
sudo systemctl restart httpd
# Success.
# ============================================
# PART 7: VERIFY
# ============================================
sudo ss -tlnp | grep 9496
# LISTEN 0 511 *:9496 *:* users:(("httpd",...))
# ============================================
# PART 8: CUSTOM POLICY (LAST RESORT)
# ============================================
sudo ausearch -m avc -ts recent | audit2allow -M myapp_custom
cat myapp_custom.te
sudo semodule -i myapp_custom.pp
# ============================================
# PART 9: PER-DOMAIN PERMISSIVE (MULTI-DENIAL)
# ============================================
sudo semanage permissive -a httpd_t
# Exercise the application, collect denials, generate policy.
sudo semanage permissive -d httpd_t
The nine parts trace the troubleshooting: reproduce, find, interpret, check port, add port, restart, verify, custom policy, and per-domain permissive.
Quick Reference
Finding Denials
| Command | Purpose |
|---|---|
ausearch -m avc -ts recent | Recent AVC denials |
ausearch -m avc -c <cmd> | Filter by command |
sealert -a /var/log/audit/audit.log | Human-readable analysis |
audit2why | Explain a denial |
The Fix Sequence
| Order | Check | Command |
|---|---|---|
| 1 | File context | restorecon -Rv |
| 2 | Boolean | setsebool -P |
| 3 | Port | semanage port -a |
| 4 | Custom policy | audit2allow |
Custom Policy
| Command | Purpose |
|---|---|
audit2allow -m <name> | Generate TE source |
audit2allow -M <name> | Generate compiled module |
semodule -i <name>.pp | Install module |
semodule -l | grep <name> | Verify module loaded |
Per-Domain Permissive
| Command | Purpose |
|---|---|
semanage permissive -a <domain> | Set domain permissive |
semanage permissive -d <domain> | Remove permissive |
Best Practices
โ Do This:
sudo ausearch -m avc -ts recent
<!-- Find the denial first --> # โ
sudo sealert -a /var/log/audit/audit.log
<!-- Interpret the denial --> # โ
sudo semanage port -a -t http_port_t -p tcp 9496
<!-- Fix the port before writing a policy --> # โ
โ Don’t Do This:
sudo ausearch -m avc -ts recent | audit2allow -M policy && semodule -i policy.pp
<!-- Run audit2allow without reviewing --> # โ
# Disable SELinux to fix the denial
<!-- Use the fix sequence instead --> # โ
# Assume every denial is a policy problem
<!-- Check context, boolean, port first --> # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
ausearch shows nothing | auditd not running | Start auditd |
| Denial is a file context | File moved with mv | restorecon -Rv |
| Denial is a boolean | Service needs a capability | setsebool -P |
| Denial is a port | Non-standard port | semanage port -a |
| Policy module too broad | audit2allow not reviewed | Review .te before install |
Real-World Examples
1. Find Denials
sudo ausearch -m avc -ts recent
2. Interpret
sudo sealert -a /var/log/audit/audit.log
3. Check Context
sudo matchpathcon -V /var/www/html/*
4. Fix Context
sudo restorecon -Rv /var/www/html
5. Check Boolean
getsebool httpd_can_network_connect
6. Toggle Boolean
sudo setsebool -P httpd_can_network_connect on
7. Add Port
sudo semanage port -a -t http_port_t -p tcp 9496
8. Generate Policy
sudo ausearch -m avc -ts recent | audit2allow -M myapp_custom
9. Install Policy
sudo semodule -i myapp_custom.pp
10. Per-Domain Permissive
sudo semanage permissive -a httpd_t
Visual
Troubleshooting Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Application fails โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ausearch -m avc -ts recent โ
โ โ Find the denial โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sealert / audit2why โ
โ โ Interpret the denial โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Check: context โ boolean โ port โ
โ โโโ Fix found โ Apply fix โ
โ โโโ No fix โ audit2allow โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Review and install custom policy โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fix Order
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. File context โ
โ restorecon -Rv โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Boolean โ
โ setsebool -P โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Port โ
โ semanage port -a โ
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Custom policy โ
โ audit2allow -M โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Find denials | ausearch -m avc -ts recent |
| Interpret denials | sealert -a or audit2why |
| Fix context | restorecon -Rv |
| Fix boolean | setsebool -P |
| Fix port | semanage port -a |
| Generate policy | audit2allow -M |
| Install policy | semodule -i |
| Per-domain permissive | semanage permissive -a |
Key takeaways:
- The
ausearchcommand finds the denial. The-m avcfilter shows the SELinux denials. The-ts recentflag limits the search to the entries after the failure. Thesealertandaudit2whycommands translate the denial into a human-readable explanation . - The fix order is context, boolean, port, policy. The file context is the most common cause, followed by a boolean that is off, followed by a port that is not permitted. The custom policy is the last resort for the cases that the first three do not cover .
- The
audit2allowoutput must be reviewed. The command grants whatever the denial requested. A denial that is caused by a misconfiguration, such as a wrong port or a wrong file path, is not a policy problem. Theaudit2allowon that denial creates a policy rule that permits the misconfiguration instead of fixing it . - The per-domain permissive is for multi-denial applications. The
semanage permissive -a <domain>command allows the application to run while logging every denial. The complete set of denials is collected and a single policy module is generated . - The
semanage port -ais the fix for a non-standard port. Thehttp_port_ttype is the type that thehttpd_tdomain can bind to. The port must be added to the type before the service can bind to it in enforcing mode .
Remember: The troubleshooting is a sequence. The ausearch finds the denial. The sealert interprets it. The context, boolean, and port are the first checks. The audit2allow is the last resort. The policy module is reviewed before installation. The per-domain permissive is the tool for collecting the complete set of denials. The exam tests the commands and the fix order.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!