SELinux

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
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ègles allow autorisent 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 policy strict/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 mails
  • ftp_home_dir — autorise le FTP à servir les répertoires personnels des utilisateurs
  • allow_user_exec_content / allow_staff_exec_content / allow_guest_exec_content — autorisent l'exécution de scripts selon le rôle SELinux
  • allow_mount_anyfile — autorise mount sur n'importe quel fichier
  • cron_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