Objectives
What the exam tests
- Configure SELinux to enforce or permissive mode persistently
- List and identify SELinux file and process context labels
- Restore default file contexts using
restorecon - Use boolean settings to modify SELinux policy behavior
- Diagnose and address routine SELinux policy violations
- Manage SELinux port labels to allow services on non-standard ports
- Investigate SELinux AVC denials with
ausearchand the audit log - Generate and apply policy modules with
audit2allow
SELinux is tested on every RHCSA exam. The most common scenario: a service is running but inaccessible — the fix is either a context relabel (restorecon), a boolean change, or a port label addition. Never set SELinux to Disabled on the exam unless explicitly required.
Coverage weight by topic
SELinux decision flow
When a process tries to access a resource, the kernel checks both DAC (standard Unix permissions) and MAC (SELinux). Both must allow the access.
DAC — Discretionary Access Control
- Standard Unix rwx permissions
- ACLs (getfacl / setfacl)
- Controlled by the file owner
- Checked first by the kernel
MAC — Mandatory Access Control
- SELinux policy rules
- Cannot be overridden by owner
- Based on context labels, not ownership
- Checked after DAC passes
If DAC denies access, SELinux is never consulted. If DAC allows but SELinux denies, the denial is logged in /var/log/audit/audit.log as an AVC denial.
SELinux modes
The three SELinux modes
| Mode | Policy enforced? | Denials logged? | Use for |
|---|---|---|---|
| Enforcing Production | Yes — access blocked | Yes | Normal operation. RHEL 9 default. |
| Permissive Debug | No — access allowed | Yes — all would-be denials | Troubleshooting without breaking services |
| Disabled Avoid | No | No | Never on exam unless required. Re-enabling requires full relabel. |
Checking and changing SELinux mode
setenforce 0 is a runtime change only. If the server reboots, it returns to the mode set in /etc/selinux/config. Always edit the config file for persistent changes.
Per-process permissive domains
Per-domain permissive mode is more targeted than setting the whole system to permissive during troubleshooting — only the specific service domain is unconfined, leaving all other policies active.
SELinux contexts
SELinux context format
Every file, directory, process, and network port has a security context label with four colon-separated components.
For the RHCSA exam, the type field (third field) is what matters. SELinux policy rules are primarily type-based — they define which process types can access which file types.
| Component | Typical values | Exam importance |
|---|---|---|
| User | system_u, unconfined_u, user_u | Low |
| Role | object_r (files), system_r (processes) | Low |
| Type | httpd_sys_content_t, sshd_t, var_t | Critical |
| Level | s0 (standard), range for MLS | Ignore on RHCSA |
Viewing contexts
restorecon — restore default context
restorecon only sets contexts according to the policy database — it does not change the policy itself. If the policy database has no entry for a path, use semanage fcontext first to add a rule, then restorecon to apply it.
semanage fcontext — managing file context rules
chcon changes contexts directly but those changes are overwritten by restorecon or a system relabel. Always use semanage fcontext -a to add a permanent rule, then restorecon to apply it.Common SELinux file type reference
| SELinux type | Typical path | Used by |
|---|---|---|
httpd_sys_content_t | /var/www/html/ | Apache web content (read-only) |
httpd_sys_rw_content_t | /var/www/html/uploads/ | Apache writable content |
httpd_log_t | /var/log/httpd/ | Apache log files |
sshd_key_t | /etc/ssh/ssh_host_* | SSH host keys |
var_t | /var/ | Generic /var content |
etc_t | /etc/ | Configuration files |
user_home_t | /home/user/ | User home directories |
tmp_t | /tmp/ | Temporary files |
svirt_sandbox_file_t | Container mounts | Podman / container volumes |
container_file_t | Container bind mounts | Rootless container volumes |
SELinux booleans
What are SELinux booleans?
Booleans are on/off switches that control specific behaviors within the SELinux policy without requiring a full policy recompile. They allow administrators to enable optional features that the policy ships with but disables by default.
Runtime change (lost on reboot)
Persistent change (survives reboot)
Managing booleans
Always use setsebool -P (with the -P flag) for persistent changes. Without -P, the change is lost when the system reboots.
Common booleans for the exam
| Boolean | When to enable |
|---|---|
httpd_can_network_connect | Apache needs to connect to a backend (proxy, database) |
httpd_can_network_connect_db | Apache needs to connect to a database server |
httpd_enable_homedirs | Apache needs to serve files from user home directories (~/public_html) |
httpd_use_nfs | Apache serves content from an NFS mount |
httpd_use_cifs | Apache serves content from a Samba/CIFS mount |
ftp_home_dir | FTP server can access user home directories |
ftpd_anon_write | FTP server allows anonymous uploads |
samba_enable_home_dirs | Samba can share home directories |
allow_httpd_anon_write | Apache can write to public_content_rw_t areas |
ssh_sysadm_login | Allow sysadm_r role to SSH in directly |
container_use_devices | Containers can use host device files |
virt_use_nfs | Virtual machines can use NFS storage |
SELinux port labels
SELinux port labeling — why it matters
SELinux controls which ports a confined process can listen on. If you configure a service to use a non-standard port (e.g., Apache on port 8443 instead of 443), SELinux will deny the bind unless that port has the correct label.
Common port type labels
| SELinux type | Default ports | Service |
|---|---|---|
http_port_t | 80, 443, 8008, 8009, 8443 | Apache httpd, nginx |
ssh_port_t | 22 | OpenSSH sshd |
ftp_port_t | 21 | vsftpd control port |
smtp_port_t | 25, 465, 587 | Postfix, sendmail |
dns_port_t | 53 | named / bind |
mysqld_port_t | 3306 | MySQL / MariaDB |
postgresql_port_t | 5432 | PostgreSQL |
nfs_port_t | 2049 | NFS server |
Troubleshooting SELinux denials
Finding AVC denials in the audit log
audit2allow and audit2why
audit2allow should be a last resort — it generates policy rules that match what happened, but may be broader than intended. Always try restorecon, then booleans, then port labels before generating custom policy modules.
sealert — user-friendly denial analysis
SELinux troubleshooting decision tree
Reading an AVC denial message
The most important fields in an AVC denial are scontext (what process is trying to access) and tcontext (what the target's context is). The tcontext type often tells you immediately what the fix is — if it shows user_home_t where you expected httpd_sys_content_t, the file has the wrong context.
Cheat sheet
Most-tested commands — quick reference
getenforcesestatussetenforce 0setenforce 1sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/configls -Z /path/to/fileps -eZ | grep httpdrestorecon -Rv /var/www/html/semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'semanage fcontext -l | grep /srvchcon -t httpd_sys_content_t /filetouch /.autorelabel && rebootgetsebool -agetsebool httpd_can_network_connectsetsebool -P httpd_can_network_connect onsemanage boolean -l | grep httpdsemanage port -l | grep httpsemanage port -a -t http_port_t -p tcp 8443semanage port -d -t http_port_t -p tcp 8443ausearch -m avc -ts recentausearch -m avc -ts recent | audit2whyausearch -m avc -ts recent | audit2allow -M mypolsemodule -i mypol.ppsemodule -lsemanage subcommand reference
| Subcommand | Manages | Key flags |
|---|---|---|
semanage fcontext | File context rules | -a add, -m modify, -d delete, -l list, -t type |
semanage port | Port labels | -a add, -m modify, -d delete, -l list, -t type, -p protocol |
semanage boolean | Boolean listing/info | -l list with descriptions and persistent values |
semanage permissive | Per-domain permissive | -a add, -d delete, -l list |
semanage user | SELinux user mappings | -l list (rarely needed on RHCSA) |
Non-standard port — exam template
Practice quiz
Question 1 of 8
You copy a web file to /var/www/html/ but Apache returns a 403 Forbidden error. Standard permissions look correct. The file has context user_home_t. What is the correct fix?
user_home_t instead of httpd_sys_content_t). This happens when files are copied from a home directory — they inherit the source context. restorecon -Rv /var/www/html/ resets all contexts in that directory to the policy defaults. Option C disables SELinux enforcement (wrong approach — never disable SELinux to fix a context issue). Option D changes Unix permissions — not the SELinux issue.Question 2 of 8
You want Apache to serve content from /srv/webdata/ permanently. Which is the correct sequence?
semanage fcontext -a -t, then (2) apply it with restorecon -Rv. Option A (chcon) works temporarily but is lost on relabel. Option C alone will not work because the policy has no entry for /srv/webdata/ — restorecon would reset it to var_t or similar. Option D references a non-existent boolean.Question 3 of 8
Which command persistently enables the SELinux boolean httpd_can_network_connect?
-P flag in setsebool makes the change persistent — it writes to the policy store so it survives reboots. Without -P, Option A changes only the runtime value and is lost on reboot. Option C — semanage boolean is for listing only, not setting. Option D — getsebool is for reading values, not setting them.Question 4 of 8
You configure sshd to listen on port 2345. After restarting sshd it fails with an SELinux denial. Which command fixes this?
semanage port -a -t ssh_port_t -p tcp 2345 adds port 2345 to the list of ports allowed for the ssh_port_t type, permitting sshd to bind to it. Option A — there is no such boolean as ssh_allow_nonstandard_ports. Option C — restorecon fixes file contexts, not port labels. Option D — chcon is for file contexts, not port labels.Question 5 of 8
What does setenforce 0 do, and is the change persistent?
setenforce 0 switches SELinux to permissive mode at runtime only. The change is lost on reboot — the system returns to whatever mode is set in /etc/selinux/config. It does not disable SELinux (that requires editing the config file and rebooting). Permissive mode still loads the policy and logs what would be denied, but does not block access.Question 6 of 8
You add a context rule with semanage fcontext -a but the files still have the wrong context. What additional step is required?
semanage fcontext -a adds a rule to the policy database but does not change the context of existing files. You must run restorecon -Rv /path/ to apply the rule to files that already exist. New files created in the path will automatically get the correct context from the policy. A reboot is not necessary.Question 7 of 8
Which command shows the most human-readable explanation of what is causing an SELinux denial and how to fix it?
ausearch -m avc -ts recent | audit2why filters the audit log for recent AVC messages and pipes them to audit2why, which translates the raw denial into a human-readable explanation of the policy rule that was violated — and often suggests the fix. Option A shows raw binary-style audit log entries which are hard to read. Option C shows SELinux status but not specific denials.Question 8 of 8
In SELinux context system_u:object_r:httpd_sys_content_t:s0, which field is most important for the RHCSA exam and determines what processes can access the file?
httpd_sys_content_t) is the most important component for the RHCSA exam. SELinux policy in targeted mode (RHEL default) is based almost entirely on type enforcement — rules define which process types can perform which operations on which file types. The user and role fields are largely fixed, and the MLS level (s0) is not used in standard RHEL targeted policy.