Table des matières

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.

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.

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.

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, …).

$ 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]

[...]
$ 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
$ 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 :

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