The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Read current modegetenforceView examples
Inspect SELinux statussestatusView examples
Show file contextsls -ldZ /srv/reporting /srv/reporting/index.htmlView examples
Show process domainsps -eZ | grep '[h]ttpd'View examples
Find recent denialssudo ausearch -m \ AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recentView examples
Analyze audit logsudo sealert -a /var/log/audit/audit.logView examples
Compare expected labelmatchpathcon -V /srv/reporting/index.htmlView examples
Add persistent mappingsudo semanage fcontext -a -t httpd_sys_content_t \ '/srv/reporting(/.*)?'View examples
Apply expected labelssudo restorecon -Rv /srv/reportingView examples
Remove local mappingsudo semanage fcontext -d '/srv/reporting(/.*)?'View examples
Inspect service booleansgetsebool -a | grep '^httpd_'View examples
Change boolean temporarilysudo setsebool httpd_can_network_connect onView examples
Persist a booleansudo setsebool -P httpd_can_network_connect onView examples
Inspect allowed portssudo semanage port -l | grep '^http_port_t'View examples
Authorize a custom portsudo semanage port -a -t http_port_t -p tcp 8443View examples
Set system permissive temporarilysudo setenforce 0View examples
Persist a permissive domainsudo semanage permissive -a httpd_tView examples
Re-enforce a domainsudo semanage permissive -d httpd_tView examples
Search allow rulessesearch -A -s httpd_t -t httpd_sys_content_t -c file -p \ readView examples
List policy modulessudo semodule -lfullView examples

SELinux adds mandatory access control after ordinary user, group, and mode checks. Treat a denial as evidence to investigate, not as a reason to disable enforcement: establish the process domain and target type, reproduce one known request, inspect the correlated audit event, and prefer a documented boolean, port type, or persistent file-context mapping. Record and review every local policy change, test its rollback, and keep the host enforcing whenever possible.

Step by step

Detailed examples

01

Establish runtime and persistent posture before troubleshooting

getenforce reports the running mode, while sestatus also exposes the policy and configured mode. Enforcing denies disallowed operations; permissive continues them while logging AVC decisions. Disabled neither enforces nor reliably labels newly created objects. A setenforce change is temporary, whereas SELINUX= in /etc/selinux/config affects later boots. Do not move a production host to permissive merely to make an application start.

Capture runtime and configured state
getenforce
sestatus
grep '^SELINUX=' /etc/selinux/config
Back to quick reference ↑
02

Confirm discretionary access and both sides of the SELinux decision

SELinux evaluates a source process context against a target object context, object class, and requested permission after normal DAC checks. Record the service domain, exact target label, ownership, modes, and mount behavior. A service running unconfined or under an unexpected domain is a deployment problem; a file carrying default_t or an unrelated service type is usually a labeling problem, not evidence that a new allow rule is needed.

Inspect process and target labels
ps -eZ | grep '[h]ttpd'
ls -ldZ /srv/reporting /srv/reporting/index.html
namei -om /srv/reporting/index.html
Back to quick reference ↑
03

Correlate one reproduced request with its complete AVC event

Reproduce a known request once, note its timestamp, and query AVC, USER_AVC, and SELinux error records. Read the source context, target context, object class, and denied permission together; adjacent SYSCALL and PATH records may supply the executable and path. If Audit is unavailable, inspect the kernel journal. sealert can summarize evidence, but its proposal is not an authorization decision. Never install an audit2allow-generated module without understanding each rule.

Collect and explain recent evidence
sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
sudo journalctl -t setroubleshoot --since '15 minutes ago' --no-pager
sudo sealert -a /var/log/audit/audit.log
Back to quick reference ↑
04

Fix non-standard paths in the file-context database, then relabel

chcon changes only the current extended attribute and can be undone by restorecon or a full relabel. For an intentional non-standard location, add a narrowly anchored semanage fcontext expression, review it, and apply it with restorecon. The mapping is persistent; restorecon changes current labels. Rollback is also two-stage: delete the exact local mapping, then use restorecon to apply whatever default mapping now wins. Test the expression against a staging path before a recursive production relabel.

Map, verify, apply, and document a web-content tree
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/reporting(/.*)?'
sudo semanage fcontext -l -C | grep '/srv/reporting'
matchpathcon /srv/reporting/index.html
sudo restorecon -Rv /srv/reporting
matchpathcon -V /srv/reporting/index.html
Back to quick reference ↑
05

Use documented policy interfaces for optional behavior

A policy boolean deliberately enables a family of allow rules, so inspect its policy documentation and blast radius before changing it. setsebool without -P changes runtime state; -P writes persistent local policy and can take longer. Likewise, a daemon listening on a non-standard port may need a persistent semanage port mapping. Check existing assignments first: use -a only for an unassigned port and -m only when intentionally changing an existing local assignment.

Review before making persistent service changes
getsebool httpd_can_network_connect
semanage boolean -l | grep '^httpd_can_network_connect'
sudo semanage port -l | grep '^http_port_t'
sudo semanage port -a -t http_port_t -p tcp 8443
Back to quick reference ↑
06

Constrain and reverse any temporary reduction in enforcement

Whole-system permissive mode allows every otherwise-denied operation and should be a short, approved diagnostic exception with active monitoring and an immediate setenforce 1 recovery step. A permissive domain limits the weakened scope, but semanage permissive creates a persistent local customization—it is not temporary merely because it is used for debugging. Remove it after evidence collection and verify the service again under enforcement. Avoid disabling SELinux; files created while disabled may be unlabeled and re-enablement requires careful relabeling.

Prefer a scoped domain and restore enforcement
sudo semanage permissive -a httpd_t
sudo ausearch -m AVC,USER_AVC -ts recent
sudo semanage permissive -d httpd_t
getenforce
Back to quick reference ↑
07

Interrogate existing policy before considering a local module

Use service-specific SELinux manual pages, sesearch, booleans, port types, and file types to determine whether the shipped policy already models the requirement. Inventory local modules and their priorities so an old override is not mistaken for vendor behavior. A local module is the last step for a legitimate access pattern that has no supported interface; build it from a reviewed minimal design, version its source, test on matching policy versions, and retain a verified uninstall path.

Search policy and inventory overrides
man httpd_selinux
sesearch -A -s httpd_t -t httpd_sys_content_t -c file -p read
sudo semodule -lfull
sudo semanage fcontext -l -C
Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Red HatUsing SELinux in Red Hat Enterprise Linux 10docs.redhat.com
  2. Red HatConfiguring SELinux for Applications and Services with Non-standard Configurationsdocs.redhat.com
  3. Red HatTroubleshooting Problems Related to SELinuxdocs.redhat.com
  4. SELinux Projectsemanage-fcontext(8)man7.org
  5. SELinux Projectsetsebool(8)man7.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback