UP | HOME
LPASRSI

Modules « Système Linux »

Vacations en licence professionnelle « Audit et Sécurité des Réseaux et Systèmes d'Information » à l'antenne de Ifs du pôle de Caen de l'IUT Grand Ouest Normandie


M62 : Sécurité Linux « avancée » — SELinux, approche pragmatique

Rappel historique

En 2000, la NSA (National Security Agency) met SELinux à disposition de la communauté, comme preuve du concept (poc : proof of concept) de contrôle d’accès obligatoire (MAC : mandatory access control) dans une architecture FLASK (Flux Advanced Security Kernel, cf. Fluke OS).

Avant de l’accepter comme partie intégrante du noyau, Linus Torvalds exige le développement d’une architecture spécifique permettant un chargement modulaire de futures autres nouvelles fonctionnalités de sécurité. C’est ainsi que naît l’API (Application Programming Interface) LSM (Linux Security Modules).

LSM est un cadre de travail (framework) pour la sécurité et fait partie intégrante du noyau Linux depuis la version 2.6. Il est intégré aux parties du noyau qui contrôlent l’accès aux fichiers, aux interfaces réseau, … Une fois porté sur l’API LSM, le code SELinux a été intégré au noyau.

Disponibilité de SELinux

La première distribution à supporter SELinux fût la Fedora Core, pilotée par Red Hat. Aujourd’hui SELinux est supporté par la grande majorité des autres distributions, parmi lesquels Gentoo et plus récemment Debian.

Pour déterminer si SELinux est activé sur un système, il faut utiliser la commande getenforce, qui — si elle est présente — renvoie le mode courant du système parmi les 3 états existants : actif (enforcing), désactivé (disabled) ou permissif (permissive). Ce dernier état ne bloque aucun accès mais journalise toutes les vérifications de la politique effectuées.

Type enforcement

SELinux décompose le système d’exploitation en deux catégories : les sujets et les objets.

Les sujets sont les processus et autres éléments « actifs », comme les utilisateurs ou les applications. Ils peuvent être de confiance ou pas.

Les objets, à l’inverse, sont les fichiers, ports de connexion (sockets), tubes, interfaces et toute autre entité plus statique qu’on peut trouver au sein du système.

À chaque objet est assigné un contexte de sécurité de type définissant qui (quel sujet) peut l’utiliser et comment (pour quoi faire).

  • <cible> <sujet> <objet>:<classe> { <permission1> <permission2> }
  • Exemple :
    • allow named_t sbin_t:dir search
    • autoriser le sujet de type named_t sur les objets de type sbin_t de la classe dir (répertoire) à effectuer des recherches

Étiquettes et politique

SELinux est fondé sur ce concept, appelé renforcement du type (TE : type enforcement).

Sur chaque partie du système d’exploitation — des utilisateurs aux fichiers en passant par les ports TCP, SELinux appose une étiquette (label) définissant les politiques de sécurité qui affectent cet objet et fournit un contexte d’utilisation.

SELinux assigne automatiquement les étiquettes aux éléments du système, mais l’administrateur peut modifier celles-ci selon ses besoins, la politique s’appliquant suivant les étiquettes et non suivant les fichiers.

Contextes

Une clé de SELinux est la compréhension et l’utilisation des contextes SELinux. Chaque élément du système est associé à un contexte, et ces contextes sont utilisés pour déterminer quels utilisateurs, applications et services ont accès à quels fichiers, répertoires et applications. Sans même comprendre le détail du mécanisme de création d’une politique de sécurité, la plupart des utilisateurs de SELinux peut gérer ses système est utilisant et modifiant les contextes.

Il existe trois type des contextes dans SELinux. Pour visualiser les contextes d’un répertoire ou d’un fichier, il suffit d’utiliser la commande ls avec l’option longue --context ou l’option courte -Z :

[olm@olm www]$ ls -Z /var/www
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html

NB : Ces options s’appliquent à de nombreuses autres commandes et permettent de connaître le contexte de sécurité des utilisateurs (id, …), des processus (ps, ss, lsof, …).

Dans le résultat fourni par la commande, c’est la partie suivante qu’il faut examiner : system_u:object_r:httpd_sys_content_t.

On y trouve les trois contextes du répertoire :

  • system_u est le contexte utilisateur,
  • object_r est le contexte de rôle utilisé seulement dans le cadre d’une application stricte,
  • httpd_sys_script_exec_t= est le contexte de type.

Contexte utilisateur

Il peut prendre trois valeurs :

  • user_u indique que n’importe quel utilisateur peut accéder au fichier (nonobstant les droits POSIX qui s’appliquent avant SELinux),
  • system_u indique que seuls les utilisateurs système peuvent accéder au fichier,
  • root indique que seul l’utilisateur ayant l’UID 0 peut accéder au fichier.

Contexte de type

C’est le contexte le plus important, sur lequel il faut porter son attention lorsque l’on modifie les permissions SELinux ou que l’on dépanne un système SELinux. Ce sont les contextes de type qui fournissent le contrôle d’accès le plus fin dans SELinux. Un système SELinux avec une politique par défaut présente un grand nombre de contextes de type. La commande semanage fcontext -l permet de les lister.

NB : les éléments entre parenthèses sont des expressions rationnelles.

[olm@olm ~] sudo semanage fcontext -l | grep "httpd_sys_content"
/srv/([^/]*/)?www(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/var/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0
/etc/htdig(/.*)?                                   all files          system_u:object_r:httpd_sys_content_t:s0
/srv/gallery2(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/trac(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/htdig(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/icons(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/glpi(/.*)?                              all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/htdig(/.*)?                             all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/drupal.*                                all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/z-push(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/svn/conf(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/icecast(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/cacti/rra(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/ntop/html(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/doc/ghc/html(/.*)?                      all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/openca/htdocs(/.*)?                     all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/selinux-policy[^/]*/html(/.*)?          all files          system_u:object_r:httpd_sys_content_t:s0

Portée de la politique SELinux

Même si activée la politique SELinux peut ne pas concerner l’ensemble du fonctionnement du système d’exploitation. Le périmètre d’application de la politique SELinux peut être :

  • ciblé (targeted), appliquée sur un sous-ensemble de services, le reste du système n’étant pas confiné (unconfined)
  • strict, l’ensemble du fonctionnement du système étant soumis au vérification SELinux.

Autres mécanismes de sécurité SELinux

Imbrication des mécanismes de sécurité

Renforcement du type
: c’est le mécanisme fondamental du contrôle d’accès obligatoire. Il est associé au principe du moindre privilège : ce qui est autorisé est le strict nécessaire au bon fonctionnement et ce qui n’est pas autorisé est interdit
Contrôle d’accès fondé sur les rôles
: n’est pas utilisé dans le cadre d’une politique ciblée
Sécurité multi-niveaux (MLS)/multi-catégories (MCS)
 

RBAC

SELinux permet également la création de rôles utilisables pour un contrôle d’accès fondé sur les rôles (RBAC : role-base access control), au sein duquel les utilisateurs (au sens SELinux : ce ne sont pas nécessairement ceux du système) sont associés à un ou plusieurs rôles, des accès leur étant fournis suivant les permissions associées à leur différents rôles. Cet ensemble de fonctionnalités de sécurité (TE et RBAC) encourage les utilisateurs sur la voie du « moindre privilège », en refusant les accès par défaut pour n’autoriser que les utilisateurs appropriés, les fichiers et applications suivant le contexte donné.

Éléments techniques

  • Architecture Flask :
    • Règles de gestion de la politique de sécurité
      • certaines règles sont obligatoires
      • d’autres règles sont conditionnelles et gérées via des booléens
      • des règles additionnelles peuvent être chargées sous forme de modules (semodule)
  • LSM :
    1. Le DAC est toujours prioritaire
    2. Grâce aux crochets (hooks) implantés dans le code, le noyau appelle le LSM
    3. Un vecteur d’accès est construit (AV : access vector)
    4. le cache des vecteurs d’accès (AVC : access vector cache) est consulté
    5. En l’absence d’une réponse dans le cache le serveur de sécurité est appelé
    6. Les décisions sont journalisées (si c’est possible techniquement et autorisé par la politique)
    7. la réponse est transmise au noyau (autorisation ou interdiction d’accès)
  • Journalisation d’audit

Autres éléments de configuration

  • Activation (setenforce)
  • Portée
  • Booléens : getsebool, setsebool
  • Fichiers et répertoires de configuration
    • /etc/selinux
    • /etc/selinux/<politique>
    • /sys/fs/selinux
    • /usr/share/selinux
    • /var/log/audit/audit.log
  • Étiquetage des fichiers, ré-étiquetage : chcon, restorecon, semanage fcontext, /.autorelabel, …

Particularités du démarrage avec SELinux

  • Chargement du noyau (pas encore de SELinux)
  • Montage de /sys/fs/selinux
  • Vérification de la version de la politique
  • Chargement de la politique
  • init

Exploitation des journaux

type=AVC msg=audit(1133209488.535:344): avc: denied { getattr } for pid=4198 comm="httpd" name="toto.html" dev=dm-0 ino=3438923 scontext=root:system_r:httpd_t tcontext=system_u:object_r:httpd_private_content_t tclass=file
  • Explications :
    • type=AVC : Cache de vecteurs d’accès
    • msg=audit(1133209488.535:344) : identifiant du message
    • avc: denied { getattr } : résultat, obtention d’un attribut refusé
    • Sujet :
      • pid=4198 : identifiant du processus sujet concerné
      • comm=« httpd » : commande correspondant au processus
      • scontext=root:system_r:httpd_t : contexte de sécurité du sujet
    • Objet :
      • name=« toto.html » : nom du fichier objet concerné
      • dev=dm-0 : périphérique où est stocké l’objet
      • ino=3438923 : numéro d’inode de l’objet
      • tcontext=system_u:object_r:httpd_private_content_t : contexte de sécurité de l’objet
      • tclass=file : classe d’objet
  • Rechercher dans les journaux d’audit : ausearch -m AVC
  • Transformer les messages en module de politique : audit2allow
  • Certains refus peuvent ne pas être journalisés (dontaudit)
  • Autres outils liés au module d’audit : aureport, auditctl, audit2why

Liens pour aller plus loin