For our Blog Visitor only Get Additional 3 Month Free + 10% OFF on TriAnnual Plan YSBLOG10
Grab the Deal

How to Configure SELinux on Linux Server – ( Guide 2026)

To configure SELinux on a Linux server, verify its status, select the correct mode (Enforcing, Permissive), and make permanent settings in /etc/selinux/config. Then label files and ports with semanage, enable required booleans via setsebool -P, and troubleshoot AVC denials using ausearch, sealert, and audit2allow to refine policy safely.

Learning how to configure SELinux on Linux server systems is essential for hardening production workloads in 2026. SELinux enforces mandatory access control to contain breaches, limit lateral movement, and reduce zero-day impact. This beginner-friendly guide walks you through modes, policies, labeling, booleans, ports, and step-by-step troubleshooting—backed by real-world hosting experience.

What Is SELinux and Why It Matters

Security-Enhanced Linux (SELinux) is a kernel-level security framework that applies mandatory access control (MAC). Instead of relying only on traditional UNIX permissions, SELinux policies define which processes (types) can access which resources (files, sockets, ports) and how. When configured correctly, it dramatically reduces the blast radius of exploits.

Key concepts you’ll use frequently:

  • Modes: Enforcing (block and log), Permissive (allow but log), Disabled.
  • Policy types: targeted (default) focuses on network-facing daemons; MLS/MCS for advanced isolation.
  • Contexts: user:role:type:level—Type is most important for admins (e.g., httpd_t, httpd_sys_content_t).
  • Booleans: Feature toggles, e.g., httpd_can_network_connect.

Prerequisites and Supported Distributions (2026)

SELinux ships by default on RHEL, Rocky Linux, AlmaLinux, CentOS Stream, and Fedora. Debian supports SELinux (optional) but Ubuntu uses AppArmor by default. Ensure these packages:

  • policycoreutils, policycoreutils-python-utils (or python3-policycoreutils)
  • setools, setools-console
  • selinux-policy, selinux-policy-targeted
  • audit, audit-libs; setroubleshoot-server (sealert) on servers

You need sudo/root access. In production, schedule a maintenance window before switching modes.

How to Configure SELinux on Linux Server (Step-by-Step Guide 2026)

1) Check SELinux Status and Mode

First confirm whether SELinux is enabled and which policy is loaded.

getenforce
sestatus

getenforce prints Enforcing, Permissive, or Disabled. sestatus shows policy type (usually targeted) and mount points.

2) Switch Modes: Temporary vs. Permanent

Use Permissive while testing, then switch to Enforcing once logs show no critical denials.

# Temporary (no reboot required)
sudo setenforce 0      # Permissive
sudo setenforce 1      # Enforcing

# Permanent (persist across reboots)
sudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
# or set permissive permanently:
# sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config

Avoid disabling SELinux in production. If you must relax rules for a specific domain, consider per-domain permissive mode instead.

3) Confirm Policy and Install Tooling

Ensure you have the default targeted policy and admin tools installed.

# RHEL/Rocky/Alma/Fedora
sudo dnf install -y policycoreutils policycoreutils-python-utils selinux-policy selinux-policy-targeted setools-console setroubleshoot-server audit

# Debian
sudo apt-get update
sudo apt-get install -y selinux-basics selinux-policy-default policycoreutils setools setools-console auditd selinux-utils

Enable and start auditd to capture detailed AVC (Access Vector Cache) denials.

sudo systemctl enable --now auditd

4) Label Files Correctly (Persistent vs. Temporary)

SELinux relies on file labels (contexts). Always prefer persistent labeling with semanage fcontext, then restorecon to apply. Avoid chcon except for quick tests.

# Example: Host a website from /srv/www/myapp
# 1) Persistently map path to an SELinux type
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www/myapp(/.*)?"

# 2) Apply the mapping to the filesystem
sudo restorecon -Rv /srv/www/myapp

# Quick, temporary alternative (discouraged for long-term):
sudo chcon -R -t httpd_sys_content_t /srv/www/myapp

Use httpd_sys_rw_content_t only for directories the web server must write to (uploads, cache), never for your entire document root.

5) Label Non-Standard Ports

If a service binds to a custom port, assign the proper SELinux port type with semanage port.

# NGINX/Apache on TCP 8080
sudo semanage port -a -t http_port_t -p tcp 8080
# Verify
sudo semanage port -l | grep http_port_t

Common types include http_port_t (web), ssh_port_t (SSH), mysqld_port_t (MySQL/MariaDB), and smtp_port_t (mail).

6) Enable Required SELinux Booleans

Booleans toggle optional permissions for services. Persist changes with -P so they survive reboots.

# List httpd-related booleans
getsebool -a | grep httpd

# Allow web apps to initiate network connections (APIs, Redis, etc.)
sudo setsebool -P httpd_can_network_connect on

# Allow serving user directories
sudo setsebool -P httpd_enable_homedirs on

# Allow sending mail from web apps
sudo setsebool -P httpd_can_sendmail on

Search for service-specific booleans (e.g., for NFS, FTP, virtualization) and enable only what you need.

7) Troubleshoot AVC Denials Like a Pro

When SELinux blocks access, it logs an AVC denial. Use these tools to pinpoint root cause.

# Recent denials
sudo ausearch -m AVC,USER_AVC -ts recent

# Readable report (setroubleshoot)
sudo sealert -a /var/log/audit/audit.log

# Explain why it was denied
sudo grep AVC /var/log/audit/audit.log | audit2why

If you must permit a legitimate action not covered by policy, generate a minimal custom module. Review carefully before loading.

# Build a local policy module from recent denials
sudo grep AVC /var/log/audit/audit.log | audit2allow -M mylocal

# Load the module
sudo semodule -i mylocal.pp

# List installed modules
sudo semodule -l

Prefer fixing labels, ports, and booleans first; policy modules are a last resort for well-understood, legitimate needs.

8) Use Per-Domain Permissive Mode for Safer Testing

Instead of disabling SELinux globally, set only the troublesome domain to permissive while you investigate.

# Make only httpd_t permissive (global mode remains Enforcing)
sudo semanage permissive -a httpd_t

# Revert later
sudo semanage permissive -d httpd_t

Real-World Examples (Web, Database, Containers)

Example A: NGINX/Apache on a Custom Document Root and Port

# Custom docroot
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/webapp/public(/.*)?"
sudo restorecon -Rv /srv/webapp/public

# Writable uploads directory
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/srv/webapp/public/uploads(/.*)?"
sudo restorecon -Rv /srv/webapp/public/uploads

# Custom port 8080
sudo semanage port -a -t http_port_t -p tcp 8080

# Allow outbound API calls
sudo setsebool -P httpd_can_network_connect on

Example B: MariaDB Listening on a Non-Default Port

# If MariaDB listens on 3307
sudo semanage port -a -t mysqld_port_t -p tcp 3307
sudo systemctl restart mariadb

Example C: Containers with SELinux (Podman/Docker)

On SELinux-enabled hosts, mount volumes with proper labels. The :z option shares a label across containers; :Z gives a private label per container.

# Podman/Docker with shared content label
podman run -v /srv/data:/data:z myimage

# Private label per container
docker run -v /srv/data:/data:Z myimage

If the container runs a web server, ensure host ports are labeled with http_port_t and host directories have web-safe file contexts.

Best Practices for SELinux in 2026

  • Keep global mode Enforcing; use per-domain permissive only for diagnosis.
  • Prefer semanage fcontext + restorecon to persist labels across relabels.
  • Document every boolean you enable; justify with a clear use case.
  • Use semanage port for any non-standard service ports.
  • Monitor audit logs continuously; integrate AVC alerts with your SIEM.
  • Avoid blanket writable labels; restrict writes to minimal subdirectories.
  • Patch regularly; policies evolve with new packages and services.

Common Mistakes to Avoid

  • Disabling SELinux due to one denial instead of fixing labels/ports/booleans.
  • Using chcon for permanent fixes (labels vanish after relabels or restorecon).
  • Granting overly broad types (e.g., httpd_sys_rw_content_t on entire docroot).
  • Loading audit2allow modules blindly without reviewing implications.
  • Ignoring auditd or setroubleshoot outputs when issues recur.

Soft-Landing to Production: A Simple Rollout Plan

  • Stage 1 (Dev/QA): Run Permissive, collect AVC logs, fix labels/ports/booleans.
  • Stage 2 (Pre-Prod): Enforcing, monitor denials, tighten policies.
  • Stage 3 (Prod): Enforcing by default, with per-domain permissive only when investigating.

When Managed Help Makes Sense

If you prefer a hardened, ready-to-scale environment, YouStable’s managed VPS and dedicated servers ship with SELinux-ready stacks, proactive monitoring, and hands-on assistance for policy tuning. That means faster deployments, fewer false positives, and safer rollouts—without sacrificing performance or developer agility.

Quick Reference: Essential SELinux Commands

# Mode & status
getenforce
sestatus

# Temporary mode switch
setenforce 0|1

# Persistent config
vi /etc/selinux/config

# File labeling (persistent)
semanage fcontext -a -t TYPE "PATH(/.*)?"
restorecon -Rv PATH

# Ports
semanage port -a -t TYPE -p tcp|udp PORT

# Booleans
getsebool -a
setsebool -P BOOLEAN on|off

# Troubleshooting
ausearch -m AVC -ts recent
sealert -a /var/log/audit/audit.log
grep AVC /var/log/audit/audit.log | audit2why
grep AVC /var/log/audit/audit.log | audit2allow -M mylocal
semodule -i mylocal.pp

FAQs: How to Configure SELinux on Linux Server

Should I disable SELinux in production?

No. Keep SELinux Enforcing in production. Use per-domain permissive mode during investigations and fix root causes via labels, ports, and booleans. Disabling removes a key layer of defense against privilege escalation and zero-day abuse.

How do I make SELinux changes persistent?

Use semanage fcontext to persist file labels, then apply with restorecon. Use setsebool -P to persist booleans. Edit /etc/selinux/config to set the boot-time mode (enforcing or permissive). Avoid chcon for permanent changes.

How can I see what SELinux is blocking?

Check /var/log/audit/audit.log and run ausearch -m AVC -ts recent. For readable summaries and remediation tips, use sealert -a /var/log/audit/audit.log. audit2why explains denials; audit2allow can propose policy rules.

Does SELinux hurt performance?

For most workloads, the overhead is negligible. SELinux policy checks are efficient and cached. The security gains far outweigh the small cost, especially for public-facing services and multi-tenant hosts.

What’s the difference between SELinux and AppArmor?

Both enforce MAC. SELinux uses labels (types) and fine-grained policies; AppArmor relies on path-based profiles. RHEL-family distributions standardize on SELinux; Ubuntu prefers AppArmor. Choose what your distro supports best and configure it thoroughly.

Conclusion

Configuring SELinux on a Linux server is straightforward when you follow a methodical workflow: set the right mode, fix labels, map ports, toggle precise booleans, and read AVC logs. By staying Enforcing and iterating safely, you gain a strong, low-overhead security layer that protects modern web stacks in 2026 and beyond.

Prahlad Prajapati

Prahlad is a web hosting specialist and SEO-focused organic growth expert from India. Active in the digital space since 2019, he helps people grow their websites through clean, sustainable strategies. Passionate about learning and adapting fast, he believes small details create big success. Discover his insights on web hosting and SEO to elevate your online presence.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top