Introduction
SELinux (Security Enhanced Linux) est un mécanisme de sécurité développé pour Linux par la NSA (National Security Agency) et utilisé principalement sur les systèmes Red Hat, CentOS et Fedora. Il améliore de manière significative la sécurité des serveurs sur lesquels il est déployé, en apportant une couche supplémentaire aux traditionnels droits d’accès aux fichiers Unix.
En contrepartie, sa complexité considérable conduit tôt ou tard à des erreurs de configuration, ce qui a pour conséquence que bon nombre d’administrateurs décident tôt ou tard de désactiver SELinux. L’objet de cet article, c’est de fournir une introduction simple à SELinux, en s’appuyant sur une série d’exemples pratiques.
DAC et MAC
Traditionnellement, Linux utilise le contrôle d’accès discrétionnaire (Discretionary Access Control – DAC). Une application tourne avec les droits d’un certain utilisateur, ce qui définit les fichiers, les répertoires et les périphériques auxquels elle peut accéder. Les services réseau comme les serveurs de bases de données, les serveurs web etc. démarrent avec les droits du superutilisateur root pour ensuite tourner avec les droits limités d’un utilisateur système. Ce système traditionnel des permissions Unix est assez simple à manipuler, mais ses possibilités de configuration restent limitées. Dès qu’un intrus réussit à prendre la main sur un service, il aura accès à une partie plus ou moins importante du système de fichiers, y compris des fichiers que le service en question n’utilise pas forcément.
C’est là où SELinux entre en jeu avec le principe du contrôle d’accès obligatoire (Mandatory Access Control – MAC). Pour simplifier, chaque processus est confiné à un domaine, et les fichiers sont étiquetés en conséquence. Un processus ne pourra accéder qu’aux fichier étiquetés pour le domaine auquel il est confiné.
Note:
Un système MAC renforce la séparation entre les informations sur la confidentialité et l’intégrité du système pour obtenir un système de confinement.
Le système de confinement est indépendant du système de droits traditionnels et il n’existe pas de notion de superutilisateur.
SELinux, c’est quoi ?
Plus concrètement, SELinux est une extension du kernel qui permet de surveiller des processus en cours d’exécution, en garantissant que ceux-ci respectent certaines règles. SELinux repose essentiellement sur deux fondements.
- Les fichiers et les processus doivent être étiquetés avec un contexte de sécurité SELinux approprié.
- Les processus surveillés par SELinux doivent respecter un certain nombre de règles prédéfinies.
L’efficacité de SELinux va donc de pair avec la qualité des règles. Notons ici que seul le distributeur Red Hat s’est donné la peine de définir une collection de règles qui tiennent la route pour une utilisation professionnelle.
Comment fonctionne SELinux ?
SELinux définit les contrôles d'accès pour les applications, processus et fichiers d'un système. Il utilise des politiques de sécurité, c'est-à-dire des ensembles de règles qui indiquent à SELinux ce à quoi un utilisateur peut accéder ou non, pour mettre en application les autorisations d'accès définies par une politique.
Lorsqu'un sujet (une application ou un processus) envoie une requête pour accéder à un objet (par exemple un fichier), SELinux consulte un cache AVC (Access Vector Cache) où sont temporairement stockées les autorisations d'accès pour les différents sujets et objets.
Si SELinux n'est pas en mesure de prendre une décision relative à l'accès en se basant sur les autorisations stockées dans le cache AVC, il envoie une requête au serveur de sécurité. Celui-ci recherche alors le contexte de sécurité de l'application ou du processus et du fichier. Puis le contexte de sécurité est appliqué depuis la base de données de politiques SELinux. L'autorisation d'accès est ensuite accordée ou refusée.
En cas de refus, le message « avc: denied » apparaît dans le fichier /var/log.messages.
SELinux Architecture
À chaque appel système, le noyau interroge SELinux pour savoir s’il autorise l’action a être effectuée.
SELinux Contexts
Les processus et les fichiers sont étiquetés avec un contexte SELinux contenant des informations supplémentaires, telles qu'un utilisateur, un rôle, un type et, éventuellement, un niveau SELinux. Lors de l'exécution de SELinux, toutes ces informations sont utilisées pour prendre des décisions de contrôle d'accès. Dans Red Hat Enterprise Linux, SELinux fournit une combinaison de contrôle d'accès basé sur les rôles (RBAC), d'application de types (TE) et, éventuellement, de sécurité à plusieurs niveaux (MLS).
L’identité d’un utilisateur dépend directement de son compte linux. Une identité se voit attribué un ou plusieurs rôles, mais à chaque rôle correspond un domaine et un seul. C’est en fonction du domaine du contexte de sécurité (et donc du rôle…) que sont évalués les droits d’un utilisateur sur une ressource.
Le contexte de sécurité est attribué à un utilisateur au moment de sa connexion, en fonction de ses rôles. Le contexte de sécurité d’un fichier est quant à lui défini par la commande chcon (change context).
SELinux Modes
SELinux propose trois modes différents.
- Dans le mode strict (Enforcing), les accès sont restreints en fonction des règles SELinux en vigueur sur la machine.
- Le mode permissif (Permissive) peut être considéré comme un mode de débogage. Les règles SELinux sont interrogées, les erreurs d’accès sont enregistrées dans les logs, mais l’accès ne sera pas bloqué.
- Lorsque SELinux est désactivé (Disabled), l’accès n’est pas restreint, et rien n’est enregistré dans les logs.
La commande getenforce vous informe sur le mode en vigueur sur votre machine.
$ getenforce Enforcing
La commande setenforce permet de basculer temporairement – jusqu’au prochain redémarrage – entre les modes strict (Enforcing) et permissif (Permissive).
$ getenforce Enforcing $ sudo setenforce 0 $ getenforce Permissive $ sudo setenforce 1 $ getenforce Enforcing
Le mode SELinux par défaut est défini dans le fichier “/etc/selinux/config”.
# /etc/selinux/config SELINUX=enforcing SELINUXTYPE=targeted
Ici, “SELINUX” prendra une des trois valeurs enforcing, permissive ou disabled. Quant à “SELINUXTYPE”, on gardera la valeur par défaut targeted, qui garantit la surveillance des principaux services réseau.
Note:
SELinux fournit deux types de règles standards :
• Targeted : seuls les démons réseaux sont protégés (dhcpd, httpd, named, nscd, ntpd, portmap, snmpd, squid et syslogd)
• Strict : tous les démons sont protégés
Lorsque SELinux est activé – autrement dit, lorsqu’on passe du mode disabled à permissive ou enforcing, il faut impérativement songer à ré-étiqueter l’ensemble des fichiers du système. Pour ce faire, il suffit de créer un fichier vide “.autorelabel” à la racine du système de fichiers avant de redémarrer.
$ sudo touch /.autorelabel $ sudo reboot
Le ré-étiquetage du système de fichiers peut prendre un certain temps, en fonction de la taille de votre installation. Pour une première utilisation, je vous conseille d’opter pour le mode permissif par défaut. Cela évite de se retrouver avec un système qui ne démarre plus en mode strict.
- Sur une installation fraîche de RHEL, CentOS ou Fedora, SELinux est activé en mode strict (Enforcing) par défaut.
SELinux States
Pour connaître l'état général (activé ou désactivé, mode courant, politique chargée, etc…), utilisez la commande “sestatus” :
$ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 31
D'une façon générale, vous pouvez consulter les informations de l'actuel contexte SELinux avec l'argument -Z (cet argument est reconnu par ps, ls, …).
- liste des contextes pour tous les processus :
$ ps -ef -Z LABEL UID PID PPID C STIME TTY TIME CMD system_u:system_r:init_t:s0 root 1 0 0 avril13 ? 00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 system_u:system_r:kernel_t:s0 root 2 0 0 avril13 ? 00:00:00 [kthreadd] system_u:system_r:kernel_t:s0 root 3 2 0 avril13 ? 00:00:00 [ksoftirqd/0] system_u:system_r:kernel_t:s0 root 5 2 0 avril13 ? 00:00:00 [kworker/0:0H] system_u:system_r:kernel_t:s0 root 7 2 0 avril13 ? 00:00:00 [migration/0] system_u:system_r:kernel_t:s0 root 8 2 0 avril13 ? 00:00:00 [rcu_bh] system_u:system_r:kernel_t:s0 root 9 2 0 avril13 ? 00:00:00 [rcu_sched] [...]
- liste des contextes pour le processus httpd :
$ ps -ef -Z | grep http system_u:system_r:httpd_t:s0 root 18413 1 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 18417 18413 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 18418 18413 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 18419 18413 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 18420 18413 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 18421 18413 0 22:10 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
- contexte des fichiers du dossier /var/www/ :
$ ls -alZ /var/www/ drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 . drwxr-xr-x. root root system_u:object_r:var_t:s0 .. drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
Les contextes des différents fichiers sur votre système sont définis par les règles SELinux installées sur votre système. Additionnellement, certains paquets peuvent fournir leur propres modules SELinux (pour la simple et bonne raison que la politique en question n'est pas intégrée à la liste générale).
Dans ce cas, on peut rencontrer deux cas de figure :
- les paquets qui intègrent directement le module SELinux (BackupPC, certains programmes PHP, …)
- les paquets qui fournissent le module SELinux sous forme de sous paquet (memcached, pure-ftpd, …)
Dans les deux cas de figure énoncés ci-dessus, le module SELinux va fournir un ensemble de règles qui permettront au programme de fonctionner correctement dans un environnement protégé par SELinux.
Gestion
La commande semanage (SE manage)permet d’administrer les règles SELinux. Syntaxe de la commande semanage
semanage [type_d_objet] [options]
Exemple :
[root]# semanage boolean -l