← Back to list

RHCSA SELinux Quick Fix Guide: Diagnose Fast, Fix Right, Verify Always

EX200 v10 | RHEL 10 Compatible

LinuxCert Guru · 2026-03-06 14:31 · 0 claps · 8.7 min read
#selinux #rhcsa #rhcsa-selinux #selinux-fix #rhel-10
Open on Medium ↗
Wiki topics: 🔓 · Open Source

RHCSA SELinux Quick Fix Guide: Diagnose Fast, Fix Right, Verify Always

EX200 v10 | RHEL 10 Compatible

The single biggest mistake candidates make with SELinux on the RHCSA exam is disabling it when something breaks. Don’t do it. It will cost you points on every task that depends on SELinux being active.

The correct approach is always: diagnose the denial → apply the targeted fix → verify → move on.

The RHCSA SELinux Mindset

Before touching anything, internalize this golden rule:

Every SELinux fix has exactly three phases — Diagnose (read the AVC), Fix (context / port / boolean), Verify (ls -Z or getsebool + functional test). Never skip verification.

Here’s the diagnostic flow you should run every single time something breaks:

Never do this on the exam: setenforce 0 or setting SELINUX=disabled as a "fix." If you disable SELinux to make something work, you will fail every subsequent task that expects SELinux to be enforcing.

The SELinux Problem Decision Tree

Use this every time a service or file access fails while SELinux is enforcing. Follow it top to bottom — the first matching branch is your fix.

Step 1 — Confirm SELinux is the cause

getenforce                        # Must return: Enforcing
ausearch -m avc -ts recent        # Look for AVC denial

No AVC found? SELinux is NOT the problem. Check:

systemctl status SERVICE
firewall-cmd --list-all
cat /etc/service-config-file

Step 2 — Read the AVC and identify the fix

Step 3 — Apply fix, then verify

# Restart the service → test → confirm no new AVCs
ausearch -m avc -ts recent        # Should be silent

10 Common SELinux Fixes (With Full Commands)

Fix 1: Wrong File Context — Service Cannot Read Its Files

Symptom: Apache/Nginx returns 403 Forbidden. Files exist and permissions look correct. Service is running.

Cause: The web content files have the wrong SELinux type. Files moved or created outside /var/www/html/ inherit the parent directory's type instead of httpd_sys_content_t.

# Step 1 — Confirm the wrong context
ls -Z /web
# Bad output:  unconfined_u:object_r:default_t:s0  index.html
# Good output: :object_r:httpd_sys_content_t:s0
# Step 2 — Check the AVC to confirm SELinux is denying
ausearch -m avc -ts recent | grep httpd
# Step 3 — Add a persistent context mapping
semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
# Step 4 — Apply the mapping to existing files
restorecon -Rv /web
# Step 5 — Verify
ls -Z /web
# All files should now show: httpd_sys_content_t
# Step 6 — Test
curl http://localhost/

Regex tip: Always use `"/path(/.)?"` to match both the directory itself and all files inside it recursively. Forgetting the regex means only the top-level directory gets the new label.*

Fix 2: Service Blocked on Non-Standard Port

Symptom: Apache configured to listen on port 8080. systemctl restart httpd fails with "Permission denied." Journal shows AVC with name_bind.

Cause: SELinux only allows httpd_t to bind ports labelled http_port_t. Port 8080 may not be in that list, or may be assigned to a different type.

# Step 1 — Check what ports are already allowed for httpd
semanage port -l | grep http
# http_port_t  tcp  80, 81, 443, 488, 8008, 8009, 8443, 9000
# Step 2 — Check if 8080 is assigned to another type
semanage port -l | grep 8080
# If output shows a different type, use -m (modify) in step 3
# Step 3a — Add port (if not yet defined)
semanage port -a -t http_port_t -p tcp 8080
# Step 3b — Modify port (if already defined under a different type)
semanage port -m -t http_port_t -p tcp 8080
# Step 4 — Verify
semanage port -l | grep http
# Should now include 8080 in the http_port_t line
# Step 5 — Restart and confirm
systemctl restart httpd
ss -tuln | grep 8080

Firewall reminder: SELinux and firewalld are independent. Even after fixing the SELinux port, you must also open the port in the firewall:

firewall-cmd --add-port=8080/tcp --permanent && firewall-cmd --reload

Fix 3: Boolean Not Enabled — Service Feature Blocked

Symptom: Web application cannot connect to a remote database or external API even though network and firewall are open. AVC shows httpd_t denied connect on tcp_socket.

Cause: httpd_can_network_connect is off by default, blocking all outbound connections from Apache.

# Step 1 — Identify which boolean applies
getsebool -a | grep httpd
# Common network booleans:
#   httpd_can_network_connect       → general outbound TCP
#   httpd_can_network_connect_db    → database connections specifically
#   httpd_can_network_relay         → proxy/relay functionality
# Step 2 — Check current state
getsebool httpd_can_network_connect
# httpd_can_network_connect --> off
# Step 3 — Enable permanently (-P flag is critical)
setsebool -P httpd_can_network_connect on
# Step 4 — Verify
getsebool httpd_can_network_connect
# httpd_can_network_connect --> on
# Step 5 — Test the application

Always use -P: Without -P, the boolean change is lost on reboot. On the exam, always make changes persistent unless explicitly told otherwise.

Fix 4: Copied File Lost Its SELinux Context

Symptom: A file was copied using cp into /var/www/html/ but Apache returns 403. The file has correct Unix permissions (644). ls -Z shows a context like admin_home_t or user_home_t.

Cause: cp by default preserves the source file's SELinux context. A file copied from a home directory brings user_home_t with it — which httpd cannot read.

# Confirm the bad context
ls -Z /var/www/html/newfile.html
# Shows: user_home_t  ← wrong
# Option A — Restore context to policy default (quickest)
restorecon -v /var/www/html/newfile.html
# Option B — Restore entire directory
restorecon -Rv /var/www/html/
# Verify
ls -Z /var/www/html/newfile.html
# Should show: httpd_sys_content_t

Prevention tip: Use mv instead of cp when moving files within the same filesystem — mv does not inherit the source context the same way. Or run restorecon immediately after copying.

Fix 5: Apache Cannot Serve Content from User Home Directories

Symptom: Apache UserDir is configured. Visiting http://server/~username/ returns 403 Forbidden. Home directory permissions are correct (711 on home dir, 644 on files).

Cause: The httpd_enable_homedirs boolean is off. SELinux blocks httpd_t from reading user_home_t files unless this boolean is explicitly enabled.

# Step 1 — Check the boolean
getsebool httpd_enable_homedirs
# httpd_enable_homedirs --> off
# Step 2 — Enable it persistently
setsebool -P httpd_enable_homedirs on
# Step 3 — Also ensure the public_html dir has correct context
ls -Zd /home/username/public_html
# Should show: httpd_user_content_t
# If not, restore it:
restorecon -Rv /home/username/public_html
# Step 4 — Restart and test
systemctl restart httpd
curl http://localhost/~username/

Fix 6: FTP Cannot Access User Home Directories

Symptom: vsftpd is configured. Users can log in but get “Permission denied” when trying to read or write files in their home directories. Unix permissions are correct.

Cause: The ftp_home_dir boolean is off by default. SELinux blocks ftpd_t from accessing user_home_t files.

# Step 1 — Check current state
getsebool ftp_home_dir
# ftp_home_dir --> off
# Step 2 — Enable persistently
setsebool -P ftp_home_dir on
# Step 3 — For anonymous FTP access to a custom directory, also set correct context:
semanage fcontext -a -t public_content_t "/var/ftp/pub(/.*)?"
restorecon -Rv /var/ftp/pub
# Step 4 — If FTP needs write access to shared dir:
setsebool -P ftpd_anon_write on
semanage fcontext -a -t public_content_rw_t "/var/ftp/pub/uploads(/.*)?"
restorecon -Rv /var/ftp/pub/uploads
# Step 5 — Restart and test
systemctl restart vsftpd

FTP Boolean Map: ftp_home_dir → user home access | ftpd_anon_write → anonymous uploads | ftpd_use_passive_mode → passive connections.

Fix 7: NFS / Samba Share Access Denied by SELinux

Symptom: Samba or NFS share is configured but clients receive access denied. Service is running, firewall is open, Unix share permissions are correct.

Cause: SELinux requires specific context types for shared directories.

Fix — Samba:

# Option A — Apply the correct type to the shared directory
semanage fcontext -a -t samba_share_t "/samba/share(/.*)?"
restorecon -Rv /samba/share
# Option B — Allow Samba to read/write home directories
setsebool -P samba_enable_home_dirs on
# Option C — Allow Samba to share any directory that user owns
setsebool -P samba_export_all_rw on
# Verify context
ls -Zd /samba/share

Fix — NFS:

# Allow NFS to export home directories
setsebool -P use_nfs_home_dirs on
# For a custom NFS export directory
semanage fcontext -a -t nfs_t "/nfsexport(/.*)?"
restorecon -Rv /nfsexport

Exam Note: Samba and NFS tasks frequently combine SELinux fixes with firewall rules. Always fix both layers — SELinux context (or boolean) AND firewall ports (firewall-cmd --add-service=samba --permanent).

Fix 8: SELinux Blocks SSH on a Custom Port

Symptom: SSH is configured to listen on port 2222. systemctl restart sshd fails. Journal shows AVC denial for name_bind on tcp port 2222.

Cause: Port 2222 is not in the ssh_port_t list. SELinux blocks sshd_t from binding to unlabelled ports.

# Step 1 — Confirm default SSH ports
semanage port -l | grep ssh
# ssh_port_t  tcp  22
# Step 2 — Check if 2222 is already assigned elsewhere
semanage port -l | grep 2222
# If empty → use -a (add). If shows another type → use -m (modify)
# Step 3 — Add the new port
semanage port -a -t ssh_port_t -p tcp 2222
# Step 4 — Verify
semanage port -l | grep ssh
# ssh_port_t  tcp  22, 2222
# Step 5 — Open port in firewall
firewall-cmd --add-port=2222/tcp --permanent
firewall-cmd --reload
# Step 6 — Restart sshd and verify
systemctl restart sshd
ss -tuln | grep 2222

Fix 9: How to Read and Act on AVC Denials

Symptom: You know SELinux is the problem but the exact fix isn’t immediately obvious.

# Run this to see recent denials
ausearch -m avc -ts recent
# Example AVC output:
type=AVC msg=audit(1706000000.123:456): avc:  denied  { read } for
pid=1234 comm="httpd"
path="/web/index.html"
dev="sda1" ino=123456
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:default_t:s0
tclass=file permissive=0

How to decode it:

# Combine filters for targeted investigation
ausearch -m avc -ts recent | grep httpd
ausearch -m avc -ts today | grep "name_bind"
# If setroubleshoot-server is installed:
sealert -a /var/log/audit/audit.log

Fix 10: Full System Relabel After SELinux Was Disabled

Symptom: SELinux was previously set to disabled in /etc/selinux/config. After re-enabling it, almost everything is broken because files have no SELinux labels at all.

Cause: When SELinux is disabled, no labels are written to new files. When you re-enable it, those unlabelled files trigger AVCs everywhere because the policy cannot match them to any type.

# Step 1 — Re-enable SELinux in config
vi /etc/selinux/config
# Set: SELINUX=enforcing
# Set: SELINUXTYPE=targeted
# Step 2 — Tell the system to relabel itself on next boot
touch /.autorelabel
# Step 3 — Reboot
# During boot, SELinux will relabel every file on all filesystems
# This can take several minutes on large systems
reboot
# Step 4 — After reboot, verify SELinux is enforcing
getenforce
sestatus

Boot time note: The /.autorelabel file triggers a full filesystem relabel during the next boot cycle, then the system reboots a second time automatically. This is normal — do not interrupt it.

Faster alternative (RHEL 10): You can also run restorecon -Rv / on a live system, but the /.autorelabel method is more reliable and is the recommended exam approach.

Quick Reference: Exam Cheat Codes

Key Boolean Reference

Universal Verify Checklist

After every SELinux fix on the exam, run through this before moving to the next task. Skipping verification is how a correct fix becomes a lost mark.

# 1. Confirm SELinux is still enforcing
getenforce   # Must return: Enforcing
# 2. Verify the fix was applied correctly
ls -Z /PATH/TO/FILE_OR_DIR              # after semanage fcontext + restorecon
semanage port -l | grep TYPE            # after semanage port
getsebool BOOLEAN_NAME                  # after setsebool
getenforce && sestatus                  # after /.autorelabel reboot
# 3. Restart the affected service
systemctl restart SERVICE
# 4. Check service is running
systemctl is-active SERVICE
# 5. Perform a functional test (curl, ssh, ftp, mount, etc.)
# 6. Check for new AVC denials — should be silent
ausearch -m avc -ts recent

Final exam tip: SELinux tasks are often combined with other tasks (firewall, service config, networking). Always fix SELinux first — it is the most common hidden blocker — then verify other layers. The order is: SELinux → firewalld → service config → functional test.

SELinux is one of the most feared topics in the RHCSA exambut with the right diagnostic pattern and a handful of targeted fixes, it becomes one of the most predictable. Use this guide to build that muscle memory, and you’ll never lose points to SELinux again.

Hands-on Practice Lab : https://linuxcert.guru/?name=rhcsa-selinux-basics

For hands-on labs and full RHCSA exam paths, visit LinuxCert.GURU


메타데이터
post_id
83e52ff9866c
slug
rhcsa-selinux-quick-fix-guide-diagnose-fast-fix-right-verify-always-83e52ff9866c
url
https://medium.com/@support_23433/rhcsa-selinux-quick-fix-guide-diagnose-fast-fix-right-verify-always-83e52ff9866c
canonical_url
https://medium.com/@support_23433/rhcsa-selinux-quick-fix-guide-diagnose-fast-fix-right-verify-always-83e52ff9866c
author_url
https://medium.com/@support_23433
status
ok
fetched_at
2026-06-27 23:56:40