SELinux 2026 : sécurité obligatoire, policies et hardening Linux

Publié le 1 février 2026

Linux
Sécurité
Administration

SELinux (Security-Enhanced Linux) est un système de contrôle d'accès obligatoire qui renforce considérablement la sécurité Linux. Ce guide explique comment maîtriser SELinux pour sécuriser vos serveurs.

Comprendre SELinux

Qu'est-ce que SELinux ?

SELinux = Security-Enhanced Linux, développé par NSA

Principe : Contrôle d'accès obligatoire (MAC - Mandatory Access Control) vs contrôle discrétionnaire standard (DAC).

Analogie :

  • Sans SELinux : Si processus compromis run en tant que root → accès total système
  • Avec SELinux : Même root limité par policies → damage containment

DAC vs MAC

DAC (Discretionary) - Linux standard :

# User possède fichier → contrôle accès
chmod 777 sensitive_file  # User peut faire ça !

MAC (Mandatory) - SELinux :

# Policies système contrôlent accès
# User ne peut PAS bypasser même avec chmod

Pourquoi SELinux ?

Protection contre :

  • Compromission processus
  • Escalade privilèges
  • Accès non autorisés
  • Zero-day exploits

Use cases :

  • Serveurs production
  • Environnements régulés (PCI-DSS, HIPAA)
  • Containers sécurisés
  • Services exposés Internet

Modes SELinux

Trois Modes

Enforcing : Applique policies, bloque violations Permissive : Log violations, n'applique PAS Disabled : SELinux désactivé (déconseillé)

Vérifier Mode

# Mode actuel
getenforce
# Enforcing

# Status détaillé
sestatus
# SELinux status: enabled
# Current mode: enforcing
# Policy: targeted

Changer Mode

# Temporaire (jusqu'au reboot)
sudo setenforce 0  # Permissive
sudo setenforce 1  # Enforcing

# Permanent
sudo nano /etc/selinux/config

SELINUX=enforcing     # enforcing, permissive, disabled
SELINUXTYPE=targeted  # Policy type

# Reboot requis pour appliquer
sudo reboot

Workflow Recommandé

# 1. Développement/Test : Permissive
setenforce 0

# 2. Observer logs, créer policies
ausearch -m avc

# 3. Tester policies
# Créer custom policies...

# 4. Production : Enforcing
setenforce 1

Contexts SELinux

Structure Context

Format : user:role:type:level

Exemple : system_u:object_r:httpd_sys_content_t:s0

  • User : SELinux user (system_u, unconfined_u)
  • Role : Role (object_r, system_r)
  • Type : Type/Domain (httpd_sys_content_t) ← Plus important
  • Level : MLS level (s0, s0-s0:c0.c1023)

Voir Contexts

# Fichiers
ls -Z
# -rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 file.txt

# Processus
ps auxZ
# system_u:system_r:httpd_t:s0 apache

# Utilisateurs
id -Z
# unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Types Courants

# Web
httpd_t                    # Apache/Nginx process
httpd_sys_content_t        # Web content (read-only)
httpd_sys_rw_content_t     # Web content (read-write)
httpd_log_t                # Web logs

# Database
mysqld_t                   # MySQL process
mysqld_db_t                # MySQL data

# SSH
sshd_t                     # SSH daemon
ssh_home_t                 # .ssh directory

# General
user_home_t                # User files
tmp_t                      # /tmp files
var_log_t                  # Logs

Gérer File Contexts

Voir Context Fichier

# Context actuel
ls -Z /var/www/html/index.html
# unconfined_u:object_r:httpd_sys_content_t:s0

# Récursif
ls -lZR /var/www/

Changer Context Temporaire

# chcon (change context) - temporaire
sudo chcon -t httpd_sys_content_t /var/www/html/newfile.html

# Récursif
sudo chcon -R -t httpd_sys_content_t /var/www/html/

# ATTENTION : Réinitialisé par restorecon !

Changer Context Permanent

# semanage - permanent
sudo semanage fcontext -a -t httpd_sys_content_t "/custom/www(/.*)?"

# Appliquer
sudo restorecon -Rv /custom/www

# Vérifier
ls -Z /custom/www

Restaurer Contexts Défaut

# Restaurer context par défaut
sudo restorecon -v /var/www/html/file.html

# Récursif
sudo restorecon -Rv /var/www/

# Forcer reset
sudo restorecon -F -Rv /var/www/

Policies SELinux

Types Policies

Targeted (défaut) : Protège services réseau Minimum : Protection minimale MLS : Multi-Level Security (très strict)

Voir Policies

# Policy actuelle
sestatus | grep Policy
# Policy: targeted

# Modules chargés
semodule -l

# Chercher policy
semodule -l | grep httpd

Booleans

Booleans = switches on/off features policies

# Lister booleans
getsebool -a

# Boolean spécifique
getsebool httpd_can_network_connect
# httpd_can_network_connect --> off

# Activer/désactiver
sudo setsebool httpd_can_network_connect on

# Permanent
sudo setsebool -P httpd_can_network_connect on

# Booleans utiles Apache/Nginx
httpd_can_network_connect     # HTTP requests externes
httpd_can_network_connect_db  # Connexion DB
httpd_can_sendmail            # Envoyer emails
httpd_enable_cgi              # Exécuter CGI
httpd_unified                 # Accès read/write

Troubleshooting SELinux

Identifier Violations

# Audit logs
sudo ausearch -m avc -ts recent

# Dernière heure
sudo ausearch -m avc -ts today

# Avec contexte
sudo ausearch -m avc -c httpd

# Grep logs
sudo grep -i denied /var/log/audit/audit.log

Exemple AVC Denial

type=AVC msg=audit(1706097600.123:456): avc: denied { read } 
for pid=1234 comm="httpd" name="file.html" dev="sda1" ino=789012
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0
tclass=file permissive=0

Analyse :

  • Process : httpd (Apache)
  • Action : read
  • File : file.html
  • Problem : httpd_t essaie lire user_home_t (pas autorisé)
  • Solution : Changer context file.html vers httpd_sys_content_t

audit2allow

# Générer policy depuis logs
sudo ausearch -m avc -ts recent | audit2allow

# Avec explication
sudo ausearch -m avc -ts recent | audit2allow -w

# Générer module policy
sudo ausearch -m avc -ts recent | audit2allow -M myapp

# Charger module
sudo semodule -i myapp.pp

# ATTENTION : Vérifier policy avant charger !
# audit2allow génère permissif, potentiel sécurité

sealert (Interface Conviviale)

# Installer
sudo yum install setroubleshoot-server

# Analyser logs
sudo sealert -a /var/log/audit/audit.log

# Output suggest solutions :
# - Boolean à activer
# - Context à changer
# - Policy à créer

Cas Pratiques

Apache/Nginx Web Server

Problème : Site web /var/www/html/newsite ne charge pas

# 1. Vérifier context
ls -Z /var/www/html/newsite
# user_home_t ← MAUVAIS

# 2. Corriger context
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html/newsite(/.*)?"
sudo restorecon -Rv /var/www/html/newsite

# 3. Si contenu doit être modifiable (CMS)
sudo chcon -R -t httpd_sys_rw_content_t /var/www/html/uploads/

# 4. Si Apache doit connecter DB
sudo setsebool -P httpd_can_network_connect_db on

# 5. Vérifier
sudo systemctl restart httpd
curl http://localhost/newsite

Custom Port Service

Problème : Apache port 8080 refusé

# Voir ports autorisés
sudo semanage port -l | grep http
# http_port_t: tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

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

# Vérifier
sudo semanage port -l | grep 8080

# Restart service
sudo systemctl restart httpd

NFS Share

# Context NFS
sudo setsebool -P nfs_export_all_rw on
sudo setsebool -P nfs_export_all_ro on

# Context export directory
sudo semanage fcontext -a -t public_content_t "/nfs/share(/.*)?"
sudo restorecon -Rv /nfs/share

Docker/Podman

# SELinux + containers
sudo setsebool -P container_manage_cgroup on

# Volume mounts
docker run -v /host/data:/container/data:z image
# :z = private mount
# :Z = shared mount

# Voir container contexts
docker inspect container | grep -i label

Custom Policies

Créer Policy Module

Scénario : Application custom /opt/myapp

# 1. Mode permissive
sudo setenforce 0

# 2. Exécuter app, générer logs
/opt/myapp/bin/server

# 3. Analyser logs
sudo ausearch -m avc -ts recent | audit2allow -M myapp

# 4. Réviser policy générée
cat myapp.te

module myapp 1.0;

require {
    type init_t;
    type myapp_t;
    class file { read write };
}

#============= myapp_t ==============
allow myapp_t init_t:file { read write };

# 5. Compiler et charger
sudo checkmodule -M -m -o myapp.mod myapp.te
sudo semodule_package -o myapp.pp -m myapp.mod
sudo semodule -i myapp.pp

# 6. Retour enforcing
sudo setenforce 1

Policy Types

# Créer file context
sudo semanage fcontext -a -t myapp_exec_t "/opt/myapp/bin(/.*)?"
sudo restorecon -Rv /opt/myapp

# Créer port
sudo semanage port -a -t myapp_port_t -p tcp 9000

# Boolean
sudo setsebool -P myapp_can_network on

Monitoring SELinux

Logs

# Audit logs principal
/var/log/audit/audit.log

# SELinux messages
/var/log/messages

# Tail temps réel
sudo tail -f /var/log/audit/audit.log | grep AVC

Statistiques

# Compter denials
sudo ausearch -m avc -ts today | grep denied | wc -l

# Top processus bloqués
sudo ausearch -m avc -ts today | grep comm | sort | uniq -c | sort -rn

Alerting

# Script monitoring
#!/bin/bash
# /usr/local/bin/selinux-monitor.sh

DENIALS=$(ausearch -m avc -ts recent | grep denied | wc -l)

if [ $DENIALS -gt 10 ]; then
    echo "SELinux: $DENIALS denials detected!" | \
        mail -s "SELinux Alert" admin@example.com
fi

# Cron
# */15 * * * * /usr/local/bin/selinux-monitor.sh

Hardening avec SELinux

Services Critiques

# SSH strict
sudo setsebool -P ssh_chroot_rw_homedirs off

# Web server minimal
sudo setsebool -P httpd_enable_homedirs off
sudo setsebool -P httpd_builtin_scripting off

# Database
sudo setsebool -P mysql_connect_any off

Confined Users

# Voir SELinux users
sudo semanage user -l

# Mapper Linux user → SELinux user
sudo semanage login -a -s user_u john

# Types users :
# unconfined_u - Pas de restrictions
# user_u       - Restreint
# staff_u      - Moins restreint (sudo)
# sysadm_u     - Admin système

MCS (Multi-Category Security)

# Isoler processus même type
# Apache instance 1
chcon -l s0:c0 /var/www/site1

# Apache instance 2
chcon -l s0:c1 /var/www/site2

# site1 et site2 isolés même si même type httpd_t

SELinux + Systemd

Service File Context

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application

[Service]
Type=simple
ExecStart=/opt/myapp/bin/server
SELinuxContext=system_u:system_r:myapp_t:s0

[Install]
WantedBy=multi-user.target

Socket Activation

# SELinux contexts sockets
sudo semanage port -a -t myapp_port_t -p tcp 9000

Troubleshooting Avancé

Mode Debug

# Activer messages détaillés
echo 1 > /sys/fs/selinux/checkreqprot

# Verbose audit
sudo auditctl -w /etc/shadow -p wa -k shadow-file

Tester Policy

# Simuler accès
sudo sesearch --allow -s httpd_t -t user_home_t -c file -p read

# Si vide = denied
# Si résultat = allowed

Exporter/Importer Policies

# Exporter
sudo semodule -e myapp
sudo semodule -E myapp.pp

# Importer autre serveur
sudo semodule -i myapp.pp

Migration vers SELinux

Activer sur Système Existant

# 1. Installer
sudo yum install selinux-policy selinux-policy-targeted

# 2. Config permissive
sudo nano /etc/selinux/config
SELINUX=permissive

# 3. Reboot
sudo reboot

# 4. Relabel filesystem (long !)
sudo touch /.autorelabel
sudo reboot

# 5. Observer logs 1 semaine
sudo ausearch -m avc -ts today

# 6. Créer policies nécessaires
# audit2allow...

# 7. Passer enforcing
sudo setenforce 1
sudo nano /etc/selinux/config
SELINUX=enforcing

# 8. Reboot final
sudo reboot

Relabel Filesystem

# Force relabel
sudo touch /.autorelabel
sudo reboot

# Ou manuel (système arrêté)
sudo fixfiles -F onboot
sudo reboot

Désactiver SELinux (Déconseillé)

Temporaire

sudo setenforce 0

Permanent (si vraiment nécessaire)

sudo nano /etc/selinux/config
SELINUX=disabled

sudo reboot

# ATTENTION : Faille sécurité !
# Utiliser permissive plutôt que disabled

Cheat Sheet

Commandes Essentielles

# Status
getenforce
sestatus

# Modes
setenforce 0/1

# Contexts
ls -Z
ps auxZ
chcon -t type file
restorecon -Rv /path

# Policies
semanage fcontext -a -t type "/path(/.*)?"
getsebool -a
setsebool -P boolean on

# Troubleshooting
ausearch -m avc -ts recent
audit2allow -w
sealert -a /var/log/audit/audit.log

# Ports
semanage port -a -t type -p tcp PORT

Bonnes Pratiques

Sécurité

□ Enforcing en production
□ Permissive seulement test/debug
□ Jamais disabled (sauf incompatibilité majeure)
□ Policies minimales (least privilege)
□ Audit logs monitoring
□ Relabel après modifications /

Workflow

# Développement
1. Permissive mode
2. Tester app
3. Analyser AVC denials
4. Créer policies
5. Tester policies
6. Enforcing mode

# Production
1. Enforcing always
2. Monitor logs
3. Alertes denials
4. Policies à jour

Documentation

# Documenter custom policies
# /etc/selinux/targeted/modules/active/modules/
# README.txt avec explication

# Commenter .te files
# "Allow myapp read config files"

Conclusion

SELinux renforce considérablement sécurité Linux :

Activer SELinux :

setenforce 1
sestatus

Modes :

  • Enforcing : Production
  • Permissive : Debug
  • Disabled : Éviter

Contexts :

ls -Z                    # Voir
chcon -t type file      # Temporaire
semanage fcontext       # Permanent
restorecon              # Restaurer

Troubleshooting :

ausearch -m avc         # Logs
audit2allow            # Générer policies
sealert -a             # Analyse

Booleans :

getsebool -a
setsebool -P boolean on

Custom policies :

audit2allow -M myapp
semodule -i myapp.pp

Avec SELinux, même compromission processus reste contenue ! 🔒

Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets.

Contactez-nous

Articles similaires qui pourraient vous intéresser