SELinux
Introduction
"Security-Enhanced Linux, abrégé SELinux, est un Linux security module (LSM), qui permet de définir une politique de contrôle d'accès obligatoire aux éléments d'un système issu de Linux.
Son architecture dissocie l'application de la politique d'accès et sa définition. Il permet notamment de classer les applications d'un système en différents groupes, avec des niveaux d'accès plus fins. Il permet aussi d'attribuer un niveau de confidentialité pour l'accès à des objets systèmes, comme des descripteurs de fichiers, selon un modèle de sécurité multiniveau (MLS pour Multi level Security). SELinux utilise le modèle Bell LaPadula complété par le mécanisme Type enforcement de contrôle de l'intégrité, développé par SCC. Il s'agit d'un logiciel libre, certaines parties étant sous licences GNU GPL et BSD."
Pourquoi SELinux
SELinux est l'implémentation de ce que l'on appelle un MAC (Mandatory Access Control) ou Contrôle d'Accès Obligatoire. Le MAC intervient après le Contrôle d'Accès Discret ou DAC (Discretionary Access Control).
Le DAC est représenté par ce que l'on appelle les ACL (Access Control Lists) qui permettent de positionner des droits (lecture → r, écriture → w ou éxecution → x) sur les fichiers en fonction des entités y accédant (utilisateur → u, groupe → g ou autres → o).
Prenons l'exemple suivant:
[jcf@centos ~]$ pwd
/home/jcf
[jcf@centos ~]$ ll
total 0
-rwxrwxr-x. 1 jcf jcf 0 24 nov. 19:33 script.sh
L'utilisateur jcf a le droit de créer un script dans son répertoire home et peut modifier les droits d’exécution: cela est laissé à sa discrétion. Il n'y aucun moyen pour l'administrateur de s'assurer des droits de chaque fichier !
Pire encore, imaginons un processus qui tourne en tant que root ou sur un compte qui posséderai les droits super utilisateur. Si une personne mal intentionnée récupère le contrôle d'un tel processus, cela signifie qu'elle aura accès aux ressources auxquelles le compte a accès. Si le processus s'exécute avec le compte root cela signifie l'intégralité du système.
Imaginez que vous autorisiez des développeur à accéder à un serveur de production. Vous voulez qu'ils puissent regarder les logs mais qu'ils soient incapable d'exécuter des commandes avec su ou sudo. Comment faire ?!? SELinux permet d'ajuster finement la granularité du contrôle d'accès. SELinux confine un processus dans un domaine et ne l'autorise à accéder aux fichiers ou interagir avec les processus des domaines autorisés.
Fonctionnement
Les paquetages
Plusieurs paquetages composent SELinux et voici la liste (pour les spins de RedHat):
- policycoreutils, policycoreutils-python: utilitaires pour gérer SELinux;
- selinux-policy: fournit les polices de référence;
- selinux-policy-targeted: fournit les politiques cible;
- libselinux-utils: fournit des outils pour gérer SELinux;
- setroubleshoot-server: fournit les outils pour déchiffrer les messages de journalisation;
- setools, setools-console: fournit les outils pour le monitoring des évenements de journalisation, les requêtes sur les politiques de filtrage et la gestion du context des fichiers;
- mcstrans: outils pour traduire les politiques au format facile à comprendre;
On peut voir les paquetages disponibles grâce ) la commande suivante:
# rpm -qa | grep selinux | sort -u libselinux-2.5-11.el7.x86_64 libselinux-python-2.5-11.el7.x86_64 libselinux-utils-2.5-11.el7.x86_64 selinux-policy-3.13.1-166.el7.noarch selinux-policy-targeted-3.13.1-166.el7.noarch
Et on peut installer / mettre à jour les paquetages grâce à la commande suivante:
# yum -y install policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans
Les différents modes
SELinux fonctionne avec différents modes:
- enforcing
- permissive
- disbaled
Dans le mode Enforcing SELinux applique la politique de sécurité et bloque tous les accès non autorisé fait par les utilisateur ET les processus, les accès bloqués étant journalisés dans les fichiers adéquats.
Le mode Permissive peut être considéré comme un état semi-actif dans le sens ou la politique n'est pas appliquée et donc les accès ne sont pas bloqués. Cependant, toutes violations à la politique de sécurité est consigné comme dans le mode Enforcing. C'est le mode parfait pour tester l'application de la politique de sécurité !
Le mode disabled désactive SELinux.
Mode et status
On peut vérifier dans quel mode on se trouve grâce à la commande suivante:
# getenforce Enforcing
On peut afficher le status grâce à la commande suivante:
# 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: 28
Le mode enforcing est le mode par défaut sur une installation fraîche de CentOS 7. On peut modifier cela grâce à la commande suivante:
# setenforce permissive
On voit bien le status modifié:
# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 28
Changement d'état
On peut modifier le mode de fonctionnement de SELinux dans le fichier /etc/selinux/config et, il suffit de modifier la ligne:
SELINUX=enforcing
- en SELINUX=disabled → pour le désactiver
- en SELINUX=Permissive → pour le effectuer des tests (permissif)
Les modifications ne prenant effet qu'au prochain redémarrage, n'oubliez pas d'utilisez la commande suivante:
# setenforce permissive ou # setenforce disabled
L'impact sur le système
On peut voir l'application de SELinux grâce à l'option Z disponible pour beaucoup de commandes:
# # ll -auZ -rw-------. root root unconfined_u:object_r:admin_home_t:s0 .bash_history drwx------. root root unconfined_u:object_r:ssh_home_t:s0 .ssh dr-xr-x---. root root system_u:object_r:admin_home_t:s0 . -rw-r--r--. root root system_u:object_r:admin_home_t:s0 .bash_logout -rw-r--r--. root root system_u:object_r:admin_home_t:s0 .bash_profile -rw-r--r--. root root system_u:object_r:admin_home_t:s0 .bashrc dr-xr-xr-x. root root system_u:object_r:root_t:s0 .. -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg -rw-r--r--. root root system_u:object_r:admin_home_t:s0 .cshrc -rw-r--r--. root root system_u:object_r:admin_home_t:s0 .tcshrc
La quatrième colonne correspond à la politique SELinux et se décompose comme suit: {! utilisateur !! rôle !! type !! niveau de sécurité (mls) |- || unconfined_u || object_r || admin_home_t || s0 |}
Les politiques
SELinux se base sur des politiques de sécurité pour déterminer les interactions entres les différents éléments du système: utilisateurs, rôles, processus et fichiers. Pour comprendre les règles qui forment les politiques de sécurité, il faut comprendre les concepts suivants.
Utilisateurs
Chaque utilisateur Linux est mappé vers un ou plusieurs utilisateurs SELinux.
On peut afficher les utilisateurs grâce à la commande suivante:
# seinfo -u Users: 8 sysadm_u system_u xguest_u root guest_u staff_u user_u unconfined_u
Sujets et objets
Sur un système Linux chaque utilisateur peut lancer des processus. Dans le monde SELinux un processus est appelé un sujet et un sujet peut affecter un objet.
Un objet est une ressource que l'on peut manipuler comme un fichier, répertoire, port, socket TCP, le curseur, etc...
Types
Le type permet de définir le contexte d'utilisation d'un objet. Par exemple, un contexte peut servir à définir qu'un fichier est une page web ou qu'il appartient au répertoire /etc.
On peut afficher les types grâce à la commande suivante:
# seinfo -t |more Types: 4792 bluetooth_conf_t cmirrord_exec_t colord_exec_t container_auth_t foghorn_exec_t ...
Domaines
On parle de domaines lorsqu'un type se retrouve appliqué à un sujets (processus). Cela permettent de cloisonner leur fonctionnement en définissant quels objets (port, fichier, etc...) sont accessible par quel sujet.
Rôles
Un rôle peut être assimilé à une passerelle qui permet de relier un utilisateur (au sens SELinux) à un domaine. Ceux sont des filtres qui permettent de décider quel utilisateur peut accéder à quel processus.
On peut afficher les rôles grâce à la commande suivante:
# seinfo -r Roles: 14 auditadm_r dbadm_r guest_r staff_r user_r logadm_r object_r secadm_r sysadm_r system_r webadm_r xguest_r nx_server_r unconfined_r
Les différents moyens d'applications
Dans le fichier de configuration figure une deuxième directive qui permet de définir comment seront appliqués les règles de sécurité:
# SELINUXTYPE= can take one of three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
Targeted
L'application ciblée et celle par défaut. Elle permet de sélectionner les sujets à confiner dans des domaines. Le reste des processus s'exécutent de manière non confiné. Les utilisateurs non rattachés sont dans le domaine unconfined_t et les sujets non rattachés sont dans le domaine unconfined_service_t.
Sur CentOS, quasiment tous les sujets qui écoutent sur un port (eg. sshd, httpd, ...) sont confinés dans un domaine (eg. sshd_t, httpd_t).
MLS
La sécurité multi-niveau (Multi-Level Security) respecte le modèle de Bell–LaPadula. Dans ce mode, chaque sujet et objet se voient attribuer un niveau de niveau de sécurité et un sujet ne peut accéder qu'à un objet du même niveau de sécurité ou d'un niveau inférieur. Prenons comme exemple les niveaux suivant:
- top secret
- secret
- confidentiel
- non classifié
Un sujet de niveau secret ne pourra pas accéder à un objet labellisé top secret mais pourra accéder aux objets d'un niveau secret et en dessous.
A l'inverse de l'application ciblée, l'application MLS s'applique sur intégrabilité du système et on conseil vivement de procéder, lors de la première fois, à une application permissive pour vérifié que le système fonctionne correctement.