← Blog / Linux & Shell

SELinux from Scratch — Why It Matters and How to Configure It

Introduction

SELinux (Security-Enhanced Linux) is one of the most effective security mechanisms in Linux systems — and one of the most frequently disabled by administrators because “something stopped working”. That’s a mistake. In this article we explain how SELinux works, why you should leave it enabled, and how to configure it properly without disabling your entire application.


What is SELinux?

SELinux is a Mandatory Access Control (MAC) system built into the Linux kernel. Unlike standard Unix permissions (DAC), SELinux operates at the level of labels and policies — independently of file permissions or ownership.

file: /etc/passwd
SELinux context: system_u:object_r:passwd_file_t:s0

nginx process:
context: system_u:system_r:httpd_t:s0
→ does httpd_t have access to passwd_file_t? NO!
→ nginx cannot read /etc/passwd even as root

SELinux Modes

sestatus
getenforce
ModeBehaviour
EnforcingPolicies are enforced — violations blocked and logged
PermissivePolicies are NOT enforced — logging only
DisabledSELinux disabled — no protection

Base Configuration

# /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted
setenforce 0   # permissive (diagnostics)
setenforce 1   # enforcing (production)

Practical Example — nginx with a Non-Standard Directory

Problem

ls -Z /data/www/
# system_u:object_r:default_t:s0 .   ← default_t context blocks nginx

Diagnostics

ausearch -m avc -ts recent | grep nginx
ausearch -m avc -ts recent | audit2why

Solution 1 — Change the file context

semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?"
restorecon -Rv /data/www/
ls -Z /data/www/
# system_u:object_r:httpd_sys_content_t:s0 index.html

Solution 2 — SELinux booleans

getsebool -a | grep httpd

setsebool -P httpd_enable_homedirs 1
setsebool -P httpd_can_network_connect 1
setsebool -P httpd_can_network_connect_db 1

Non-Standard Ports

semanage port -l | grep http_port_t
# http_port_t  tcp  80, 443, 8008, 8080, 8443

semanage port -a -t http_port_t -p tcp 9000

Creating Custom Policy Modules

ausearch -m avc -ts recent > /tmp/avc.log
audit2allow -i /tmp/avc.log -M myapp_policy
cat myapp_policy.te   # IMPORTANT — read before applying!
semodule -i myapp_policy.pp

Most Common Issues and Solutions

ProblemCauseSolution
Nginx 403 with correct permissionsWrong SELinux contextsemanage fcontext + restorecon
Service can’t connectBoolean disabledsetsebool -P httpd_can_network_connect 1
Non-standard port blockedPort has no labelsemanage port -a

What You Should Never Do

# DON'T do this!
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

Summary

SELinux is not the administrator’s enemy — it’s an additional layer of protection. Key principles:

  1. Never disable SELinux — always diagnose the problem
  2. Use audit2why and sealert for diagnostics
  3. Fix issues via semanage fcontext, booleans or audit2allow
  4. Test changes on staging before production

The time invested in learning SELinux pays off at the first attack attempt.