The service starts but nothing connects
You installed a custom web server on a non-standard port, or you moved your home directory to a new partition. The service starts, but nothing connects. You check the logs and see Permission denied. You check firewalld, and the rules look fine. You check file permissions with ls -l, and the user has full read and write access. The culprit is almost certainly SELinux.
You found a forum post telling you to run setenforce 0. The service works immediately. You feel relieved. Then you remember reading that disabling SELinux is a bad idea, but you don't know what the alternatives are or how to fix the root cause. You need to understand the three modes, how to switch between them safely, and why "Disabled" is a trap.
How SELinux modes work
Standard Linux permissions rely on Discretionary Access Control. The file owner decides who can read or write the file. SELinux adds Mandatory Access Control on top of that. The kernel enforces a policy that defines what processes can access what files, regardless of file ownership.
Think of a building with a bouncer. Standard permissions are the keycard system. If you have the right keycard, you get in. SELinux is the bouncer. The bouncer has a list of rules. Even if you have a keycard, the bouncer checks the list. If the list says "No web servers in the server room," the bouncer stops you.
The mode determines what the bouncer does when a rule is violated.
Enforcing is the default. The bouncer stops the violation and writes a note in the log. The action is blocked. This is the secure state.
Permissive is the diagnostic state. The bouncer writes a note in the log but lets the action proceed. Nothing is blocked. This mode proves that SELinux is the cause of a failure without breaking the system.
Disabled turns off the bouncer entirely. The kernel module does not load. No rules are checked. No violations are logged. The system relies only on standard permissions. Re-enabling SELinux from this state is difficult and risky.
Checking and changing modes
Use getenforce to see the current runtime mode. This command queries the kernel directly. It returns Enforcing, Permissive, or Disabled.
# Check the current runtime mode.
# The output is a single word: Enforcing, Permissive, or Disabled.
getenforce
Use setenforce to switch modes at runtime. This change applies immediately and lasts until the next reboot. The command takes 1 for Enforcing and 0 for Permissive. It cannot switch to or from Disabled.
# Switch to Permissive mode temporarily.
# The kernel evaluates policies but allows all actions.
# Use this to confirm SELinux is blocking a service without stopping the service.
sudo setenforce 0
# Switch back to Enforcing mode.
# The kernel blocks policy violations immediately.
sudo setenforce 1
To make a change permanent, edit the configuration file. The file lives in /etc/selinux/config. Never edit files in /usr/lib/selinux/. Those files ship with packages and get overwritten on updates. User configuration belongs in /etc/.
# /etc/selinux/config
# This file controls the mode at boot time.
# SELINUX= can take one of these three values:
# enforcing - Security policy is enforced.
# permissive - No security policy is enforced, but violations are logged.
# disabled - No security policy is loaded. No logging occurs.
SELINUX=enforcing
# SELINUXTYPE= specifies the policy type.
# targeted is the default on Fedora and covers most system services.
# mls is for Multi-Level Security environments.
# Do not change this unless you have a specific requirement for MLS.
SELINUXTYPE=targeted
After editing the file, the change takes effect on the next reboot. If you switch from disabled to enforcing or permissive, the system may need to relabel the filesystem. Relabeling assigns security contexts to every file. This process can take a long time on large disks. Schedule the reboot during a maintenance window.
Verify the change
Run sestatus to confirm the mode and check the policy version. This command provides more detail than getenforce. It shows the current mode, the mode set in the config file, and whether MLS is enabled.
# Display detailed SELinux status.
# Look for "Current mode" and "Mode from config file".
# These should match after a reboot.
sestatus
If you see Current mode: Permissive and Mode from config file: enforcing, the runtime mode differs from the boot configuration. A reboot will restore Enforcing mode.
Run journalctl -t setroubleshoot to see human-readable summaries of denials. The setroubleshoot service parses audit logs and generates friendly messages. This is the first place to look when a service fails.
# Show SELinux denial summaries.
# The output includes the affected process, the resource, and a suggested fix.
# Use -n 20 to limit output to the last 20 messages.
journalctl -t setroubleshoot -n 20
Check the status before restarting a service. Restarting a service while in Enforcing mode will block it again if the context is wrong. Use Permissive mode to test, then fix the context or policy.
Common pitfalls and error messages
The setenforce command fails silently or prints an error if SELinux is disabled. You cannot switch modes at runtime when the kernel module is not loaded.
setenforce: SELinux is disabled
If you see this message, you must edit /etc/selinux/config and reboot. You cannot use setenforce to recover.
Switching from Disabled to Enforcing often requires a filesystem relabel. If the contexts are missing or wrong, services will fail to start. The boot log will show a relabeling message. Wait for the relabel to finish. Interrupting the process can leave the filesystem in an inconsistent state.
Relabeling in progress...
Do not disable SELinux to fix a permission error. Use Permissive mode to identify the denial, then fix the root cause. The root cause is usually a missing file context or a custom port that needs a policy module.
When you see a denial, the error in the logs looks like this:
type=AVC msg=audit(1698765432.123:456): avc: denied { name_connect } for pid=1234 comm="httpd" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket
The denied keyword indicates a block. The comm field shows the process. The dest field shows the port or resource. The scontext and tcontext show the source and target security contexts. Read the setroubleshoot summary to translate this into a fix.
Editing /etc/selinux/config with the wrong syntax breaks the boot. The parser expects SELINUX=value with no spaces around the equals sign. A typo can cause the system to drop to an emergency shell. Always back up the file before editing.
# Back up the config file before making changes.
# This allows you to restore the original settings if the edit causes a boot failure.
sudo cp /etc/selinux/config /etc/selinux/config.bak
Use restorecon to fix file contexts. If you moved a file or created a new directory, the context might be wrong. restorecon resets the context based on the file path and policy rules.
# Restore the default security context for a file or directory.
# The -v flag shows changes. The -r flag applies recursively.
# Run this on the affected path to fix context errors.
sudo restorecon -rv /path/to/directory
When to use each mode
Use Enforcing when you are running a production system or a desktop where security boundaries matter. This is the default and recommended state.
Use Permissive when you are debugging a service that fails with permission errors and you need to see what SELinux would block without stopping the service. This mode provides logs while allowing operations.
Use Disabled only when you are running legacy software that cannot be booted with the SELinux kernel module loaded, or when you are in a fully isolated lab environment where security is not a concern. Re-enabling SELinux later requires a full relabel and carries risk.
Use setenforce when you need to test a mode change immediately without rebooting the machine. This is useful for quick validation.
Edit /etc/selinux/config when you need the mode to persist across reboots. Always verify the syntax before saving.
Permissive mode is your diagnostic tool. Disabled mode is a sledgehammer. Use the tool.