SELinux
| Fiche express | |
|---|---|
| Domaine | Sécurité Linux (contrôle d'accès obligatoire — MAC) |
| Commandes | getenforce · semanage · setsebool · restorecon
|
| Contexte | RHEL/CentOS/Fedora — policy targeted par défaut
|
| Voir aussi | Iptables (défense en profondeur complémentaire) · Options selinux · Selinux samba · Star |
SELinux (Security-Enhanced Linux) ajoute un contrôle d'accès obligatoire (MAC) par-dessus
les permissions Unix classiques (DAC — utilisateur/groupe/autres). Même un processus root peut
se voir refuser une action si elle n'est pas autorisée par la politique. Chaque processus et
chaque fichier porte une étiquette (contexte de sécurité) sous la forme
utilisateur:rôle:type:niveau, et la policy targeted (la plus courante)
n'applique des règles strictes qu'aux démons réseau et services sensibles, laissant le reste du
système en mode permissif de fait.
Modes de fonctionnement
getenforce # mode courant : Enforcing / Permissive / Disabled
setenforce 1 # bascule à chaud en enforcing
setenforce 0 # bascule à chaud en permissive (pas de blocage, juste du log)
Persistance dans /etc/selinux/config (un changement ici nécessite un reboot,
contrairement à setenforce) :
SELINUX=enforcing # enforcing | permissive | disabled
SELINUXTYPE=targeted # targeted | minimum | mls
⚠️ Passer de disabled à enforcing/permissive nécessite
un relabelling complet du système au reboot suivant (touch /.autorelabel ou
automatique selon la distribution) — sans quoi les contextes de fichiers sont incohérents et le
système peut refuser de démarrer correctement.
Statut détaillé (mode, policy chargée, répertoire racine de la policy) :
sestatus -v
Modèle de contrôle d'accès
SELinux combine plusieurs mécanismes, dont seuls les deux premiers sont réellement actifs
avec la policy targeted par défaut :
- DAC (Discretionary Access Control) — le modèle Unix classique (utilisateur/groupe/autres), toujours actif en-dessous de SELinux.
- Type Enforcement (TE) — mécanisme principal de la policy
targeted: chaque processus s'exécute dans un domaine (type), chaque objet (fichier, socket…) porte un type, et des règlesallowautorisent explicitement certaines interactions domaine → type. - Role-Based Access Control (RBAC) — organise les utilisateurs SELinux autour de rôles ; peu déterminant avec la policy
targeted, plus pertinent en policystrict/mls. - Multi-Level Security (MLS) — niveaux de classification hiérarchiques ; peu utilisé en pratique, souvent masqué par défaut.
Vocabulaire du langage TE
allow— autorise une action (read, write, append, execute, getattr, setattr, lock, link, unlink, rename, ioctl…) d'un domaine vers un type.type— définit un type (ex.httpd_sys_content_t).auditallow/dontaudit— force ou supprime l'écriture d'un évènement AVC dans les journaux pour une règle donnée.type_transition— permet de déroger à l'héritage habituel des règles lors de l'exécution d'un processus.- file context — spécifie les contextes de sécurité attendus pour une arborescence de fichiers, utilisé lors d'un relabel.
Contexte de l'utilisateur, d'un processus
id -Z # contexte de sécurité de l'utilisateur courant
ps -Z # contexte de sécurité des processus (aussi utilisable ps -Zax)
cp -a # copie un fichier en conservant son contexte
cp -Z # copie un fichier en fixant explicitement un contexte
Utilisateurs SELinux (rôles)
À ne pas confondre avec les utilisateurs Unix : un utilisateur Unix est mappé vers un utilisateur SELinux, qui détermine les rôles et donc les privilèges disponibles.
- guest_u — pas d'interface graphique, pas de réseau, pas d'accès à
su/sudo - xguest_u — interface graphique, réseau limité au navigateur web
- user_u — interface graphique et réseau complets, pas de
sudo - staff_u — comme user_u, plus
sudo - unconfined_u — accès système complet, non confiné
semanage login -l # mapping utilisateurs Unix -> SELinux
semanage login -m -S targeted -s "user_u" -r s0 __default__ # utilisateur Unix par défaut -> user_u
Contextes de fichiers
ls -Z /var/ftp/
# drwxr-xr-x root root system_u:object_r:public_content_t pub
Lecture du contexte : system_u (utilisateur SELinux) : object_r
(rôle, toujours object_r pour un fichier) : public_content_t (type, la partie qui
compte pour les règles de la policy).
chcon -R -u system_u -t public_content_t /ftp # changement ponctuel, non persistant
chcon -R -t public_content_rw_t /ftp # variante lecture/écriture
chcon -R --reference=/var/ftp /ftp # copie le contexte d'un répertoire de référence
restorecon -Rv /ftp # restaure le contexte attendu par la policy
⚠️ chcon modifie le contexte en place mais ne le persiste pas : un
restorecon ou un relabelling futur écrasera le changement. Pour qu'un nouveau
chemin garde son contexte de façon durable, il faut l'enregistrer dans la policy avec
semanage fcontext puis appliquer avec restorecon :
semanage fcontext -l # lister les règles de contexte existantes
semanage fcontext -a -t httpd_sys_content_t '/virtual(/.*)?' # ajouter une règle pour un nouveau répertoire
restorecon -Rv /virtual # appliquer la règle enregistrée
semanage fcontext -d -t httpd_sys_content_t '/virtual(/.*)?' # supprimer la règle
Lors d'un déplacement de fichier (contrairement à une copie, un mv ne
recalcule pas le contexte), il faut le restaurer explicitement :
restorecon -v /var/www/html/index.html
restorecon -Rv -n /var/www/html # -n : simulation, prévient le relabel sans l'appliquer
Régénérer les contextes des répertoires personnels d'après la policy (utile après une migration ou une réorganisation de comptes) :
genhomedircon
Booléens
Les booléens activent/désactivent des blocs entiers de règles sans toucher à la policy compilée — pratique pour des bascules de comportement courantes (ex. autoriser httpd à se connecter en réseau).
getsebool -a # toutes les valeurs actuelles
getsebool ftp_home_dir # une valeur précise
semanage boolean -l # idem, avec description
semanage boolean -l -C # uniquement les booléens modifiés par rapport au défaut
setsebool ftp_home_dir 1 # changement à chaud (non persistant au reboot)
setsebool -P ftp_home_dir 1 # changement persistant (-P réécrit la policy)
togglesebool ftp_home_dir # bascule la valeur actuelle (non persistant)
Sur les noyaux récents, l'arborescence virtuelle est exposée sous
/sys/fs/selinux/booleans/ (l'ancien chemin /selinux/booleans/ est
obsolète mais peut encore traîner dans de la documentation ou des scripts anciens).
Quelques booléens fréquemment utilisés :
httpd_can_network_connect— autorise Apache/nginx à ouvrir des connexions sortantes (proxy, appels API)httpd_can_sendmail— autorise un service web à envoyer des mailsftp_home_dir— autorise le FTP à servir les répertoires personnels des utilisateursallow_user_exec_content/allow_staff_exec_content/allow_guest_exec_content— autorisent l'exécution de scripts selon le rôle SELinuxallow_mount_anyfile— autorisemountsur n'importe quel fichiercron_can_relabel— autorise les jobs cron à changer le contexte de fichiers
Catalogue plus large de booléens classés par service (HTTPD, FTP, NFS, Samba, SMTP, SSH) : voir Options selinux.
Ports réseau
Un service ne peut se lier qu'aux ports déjà étiquetés pour son type (ex. httpd ne peut pas
écouter sur un port qui n'est pas taggué http_port_t) :
semanage port -l # lister les associations port <-> type
semanage port -a -t http_port_t -p tcp 8080 # ajouter un port à un type existant
semanage port -m -t http_port_t -p tcp 8080 # modifier une association existante
semanage port -d -t http_port_t -p tcp 8080 # supprimer
Audit et dépannage
Toute action bloquée par SELinux génère un événement AVC (Access Vector Cache) dans les logs
d'audit — c'est le premier réflexe en cas de refus inexpliqué. Ces évènements sont collectés
par le service auditd, dans /var/log/audit/audit.log (et non dans
/var/log/messages) :
systemctl status auditd # vérifier que la collecte est active
ausearch -m avc -c sudo # évènements AVC liés à une commande précise
ausearch -m avc -ts recent # évènements AVC récents, toutes commandes
sealert -a /var/log/audit/audit.log # analyse lisible des refus + suggestions de correction
# Générer un module de policy à partir des refus observés (à auditer avant application)
audit2allow -a -M mypol
semodule -i mypol.pp
⚠️ audit2allow autorise exactement ce qui a été refusé — il ne fait aucune
vérification de pertinence. Ne jamais l'utiliser en aveugle en production : relire le module
généré (cat mypol.te) avant de l'installer avec semodule.
Méthode de diagnostic type : identifier le contexte du processus bloqué et celui de la ressource visée, puis vérifier dans la policy si la règle existe :
ps -eZ | grep httpd # contexte du processus
ls -Zd /var/www/html/ # contexte de la ressource visée
sesearch --allow -s httpd_t -c file -p write # la policy autorise-t-elle l'écriture ?
Exemple : générer un module à partir d'un refus observé
grep smtpd_t /var/log/audit/audit.log | audit2allow -m postgreylocal > postgreylocal.te
cat postgreylocal.te
module postgreylocal 1.0;
require {
type postfix_smtpd_t;
type postfix_spool_t;
type initrc_t;
class sock_file write;
class unix_stream_socket connectto;
}
#============= postfix_smtpd_t ==============
allow postfix_smtpd_t initrc_t:unix_stream_socket connectto;
allow postfix_smtpd_t postfix_spool_t:sock_file write;
Après relecture du .te généré, compiler et charger le module :
grep smtpd_t /var/log/audit/audit.log | audit2allow -M postgreylocal
semodule -i postgreylocal.pp
Gestion des modules de policy
semodule -l # lister les modules de policy installés
semodule -i monmodule.pp # installer/charger un module compilé
semodule -r monmodule # retirer un module installé
checkmodule -M -m -o monmodule.mod monmodule.te # compiler un module source (.te) en .mod
semodule_package -o monmodule.pp -m monmodule.mod # empaqueter un module installable par semodule
Outils d'inspection de la policy (nécessitent généralement le paquet
setools/setroubleshoot selon la distribution) :
sesearch --allow | grep httpd_t # recherche de règles autorisées pour un domaine donné
seinfo # informations générales sur la policy chargée
apol # exploration graphique de la policy (nécessite une interface graphique)
Politique stricte et changement de rôle
Au-delà de la policy targeted par défaut, une policy strict
applique le contrôle d'accès à l'ensemble du système et active véritablement le RBAC — un
changement de policy qui nécessite un relabel complet et un reboot :
fixfiles relabel
reboot
Changer de rôle SELinux pour une session (pertinent en policy strict, où les
rôles sont réellement cloisonnés) :
newrole -r sysadm_r
Labo : booléen et accès CGI
Exemple concret de l'effet d'un booléen, avec un script CGI Apache :
vi /var/www/cgi-bin/bonjour.cgi
chmod +x /var/www/cgi-bin/bonjour.cgi
lynx -dump 'http://localhost/cgi-bin/bonjour.cgi'
L'accès au script dépend de l'état du booléen httpd_enable_cgi :
getsebool httpd_enable_cgi
setsebool httpd_enable_cgi 1
Paquets utiles
yum install selinux-policy-devel # nécessaire pour compiler des modules (audit2allow -M, checkmodule)
yum install policycoreutils-python setroubleshoot # accès aux commandes semanage et sealert (RHEL6/7 ; policycoreutils-python-utils et python3-policycoreutils sur les versions plus récentes)
mandb # regénère l'index des pages de man après installation
man -k _selinux # liste toutes les pages de man liées à SELinux (dont *_selinux(8) par service)
Voir aussi
- Iptables — pare-feu réseau (DAC/netfilter), complémentaire au contrôle d'accès obligatoire de SELinux
- Options selinux — catalogue de booléens par service (HTTPD, FTP, NFS, Samba, SMTP, SSH)
- Selinux samba — approfondissement SELinux appliqué à Samba (paquets, ports, contextes)
- Star — archivage préservant les contextes SELinux et ACL