Gentoo Logo

Manuel Gentoo SELinux

Table des matières :

A. Installer Gentoo SELinux

1. Installation de Gentoo SELinux

1.a. Installation de Gentoo SELinux

Attention : Pour le moment, SELinux n'est supporté que sur les serveurs. Les stations de travail seront supportées plus tard.

La procédure d'installation d'un système Gentoo SELinux est identique à celle d'un système Gentoo normal. Suivez simplement les instructions décrites dans le Manuel Gentoo en tenant compte des remarques qui suivent. Le système sera par la suite converti en SELinux grâce au Guide de conversion vers SELinux.

1.b. Remarques concernant l'installation

Les systèmes de fichiers

Seuls ext2, ext3, JFS et XFS sont supportés pour le moment.

Les utilisateurs de XFS doivent utiliser des inodes de 512 octets plutôt que la taille par défaut de 256 octets. SELinux utilise les attributs étendus pour stocker les étiquettes de sécurité des fichiers, mais, comme XFS les place dans l'inode, si l'inode est trop petit, un bloc supplémentaire sera utilisé rien que pour stocker les étiquettes, ce qui gaspillera beaucoup d'espace disque et ralentira le système à cause des opérations supplémentaires pour chaque fichier.

Exemple de code 2.1 : Exemple de création de système de fichiers XFS

# mkfs.xfs -i size=512 /dev/hda3

Le noyau

Attention : SELinux ne supporte pas XFS avec les noyaux 2.6.14 et 2.6.15.

Vous pouvez regarder de suite la partie de ce guide qui concerne les options à activer pour avoir SELinux, afin de ne pas recompiler plusieurs fois votre noyau inutilement.

B. Conversion vers Gentoo SELinux

1. Préliminaires

1.a. Changer le profil Gentoo

Attention : SELinux n'est supporté qu'avec ext2/3, XFS ou JFS. Les autres systèmes de fichiers ne gèrent pas les attributs étendus, une fonctionnalité requise par SELinux.

Attention : Vous devez commencer par migrer au moins vers le profil 2006.1 (ou plus récent) sous peine d'observer des résultats imprévisibles.

Important : Comme d'habitude, conservez un LiveCD sous la main au cas où quelque chose se passerait mal.

Tout d'abord, basculez vers le profil SELinux de votre architecture :

Exemple de code 1.1 : Changer de profil

# rm -f /etc/make.profile

x86 :
# ln -sf /usr/portage/profiles/selinux/2007.0/x86 /etc/make.profile
x86 (hardened) :
# ln -sf /usr/portage/profiles/selinux/2007.0/x86/hardened /etc/make.profile
AMD64 :
# ln -sf /usr/portage/profiles/selinux/2007.0/amd64 /etc/make.profile
AMD64 (hardened) :
# ln -sf /usr/portage/profiles/selinux/2007.0/amd64/hardened /etc/make.profile
PPC :
# ln -sf /usr/portage/profiles/selinux/2007.0/ppc /etc/make.profile
SPARC64 :
# ln -sf /usr/portage/profiles/selinux/2007.0/sparc64 /etc/make.profile

Important : N'utilisez aucun autre profil qu'un de ceux listés ci-dessus même s'ils vous semblent périmés. De nouveaux profils SELinux ne sont pas forcément créés aussi souvent que les profils Gentoo par défaut.

Important : Le profil SELinux a considérablement moins de paramètres USE activés que le profil par défaut. Utilisez emerge --info pour vérifier si certains paramètres USE doivent être réactivés dans votre make.conf.

Note : Il n'est pas nécessaire d'ajouter le paramètre USE selinux puisque le profil SELinux s'en charge à votre place.

Note : Vous pourriez rencontrer ce message de Portage : « !!! SELinux module not found. Please verify that it was installed. » C'est normal, on s'en occupera plus tard.

1.b. Mise à jour des en-têtes du noyau

Nous allons commencer par mettre à jour les paquets essentiels. Tout d'abord, vérifiez la version des en-têtes du noyau qui sont installés.

Exemple de code 2.1 : Vérifier la version des en-têtes du noyau

# emerge -s linux-headers
(ou bien, si vous avez installé gentoolkit)
# equery list -i linux-headers

Si la version des en-têtes est inférieure à 2.4.20, vous devrez les mettre à jour.

Exemple de code 2.2 : Mise à jour des en-têtes du noyau

# emerge \>=sys-kernel/linux-headers-2.4.20

1.c. Mise à jour de la Glibc

Si vous venez de mettre à jour les en-têtes du noyau ou bien si vous n'êtes pas sûr que votre Glibc ait été compilée avec des en-têtes suffisamment récents, vous devez absolument la mettre à jour.

Exemple de code 3.1 : Recompilation de la Glibc

# emerge glibc

Important : C'est une étape critique. La Glibc doit être compilée avec des en-têtes Linux suffisamment récents ou bien certaines opérations échoueront.

2. Démarrer un noyau SELinux

2.a. Installer un noyau SELinux

Il est temps d'installer un noyau contenant SELinux. Un noyau 2.6 est requis, nous vous recommandons le paquet hardened-sources.

Attention : Les noyaux 2.6.14 et 2.6.15 ne doivent pas être utilisés par les utilisateurs de XFS car des bogues affectent le support XFS de SELinux.

Exemple de code 1.1 : Installer un noyau contenant SELinux

(Ce doit forcément être un noyau 2.6.)
# emerge hardened-sources

2.b. Compiler le noyau avec options SELinux

Le noyau doit être compilé avec le support des modules de sécurité, de SELinux, de devpts et des étiquettes de sécurité des attributs étendus des systèmes de fichiers. Référez-vous au guide principal d'installation pour les autres options du noyau.

Exemple de code 2.1 : Location des options requises dans menuconfig

Dans « Code maturity level options »
[*] Prompt for development and/or incomplete code/drivers

Dans « General setup »
[*] Auditing support
[*]   Enable system-call auditing support

Dans « File systems »
<*> Second extended fs support (pour ext2)
[*]   Ext2 extended attributes
[ ]     Ext2 POSIX Access Control Lists
[*]     Ext2 Security Labels
<*> Ext3 journalling file system support (pour ext3)
[*]   Ext3 extended attributes
[ ]     Ext3 POSIX Access Control Lists
[*]     Ext3 Security labels
<*> JFS filesystem support (pour JFS)
[ ]   JFS POSIX Access Control Lists
[*]   JFS Security Labels
[ ]   JFS debugging
[ ]   JFS statistics
<*> XFS filesystem support (pour XFS)
[ ]   Realtime support (EXPERIMENTAL)
[ ]   Quota support
[ ]   ACL support
[*]   Security Labels

Dans « Pseudo filesystems » (via « File systems »)
[ ] /dev file system support (EXPERIMENTAL)
[*]   /dev/pts Extended Attributes
[*]     /dev/pts Security Labels    
[*] Virtual memory file system support (former shm fs)
[*]   tmpfs Extended Attributes
[*]     tmpfs Security Labels

Dans « Security options »
[*] Enable different security models
[*]   Socket and Networking Security Hooks
<*>   Default Linux Capabilities
[*] NSA SELinux Support
[ ]   NSA SELinux boot parameter
[ ]   NSA SELinux runtime disable
[*]   NSA SELinux Development Support
[ ]   NSA SELinux AVC Statistics
(1)   NSA SELinux checkreqprot default value
[ ]   NSA SELinux enable new secmark network controls by default
[ ]   NSA SELinux maximum supported policy format version

Note : Les options disponibles peuvent très légèrement varier selon la version du noyau que vous utilisez. Les autres options des attributs étendus devraient être désactivées.

Les étiquettes de sécurité des attributs étendus doivent être activées pour devpts et pour tous vos types de systèmes de fichiers. Devfs n'est pas utilisable avec SELinux et doit donc être désactivé. Certaines options n'existent pas dans les noyaux 2.6 plus vieux, telles que le support de l'audit ou « runtime disable ». Dans les noyaux plus récents, le support des attributs étendus pour proc et tmps sont activés par défaut et l'option n'apparait pas dans le menuconfig.

Attention : N'activez pas l'option « SELinux MLS Policy » si elle est disponible, car elle n'est pas supportée et empêchera votre machine de démarrer.

Maintenant, compilez et installez votre noyau et ses modules. Ne redémarrez pas encore le système.

2.c. Mise à jour du fstab

SELinuxFS doit également être monté au démarrage. Ajoutez cette ligne à votre /etc/fstab :

Exemple de code 3.1 : Activation du selinuxfs au démarrage

none	/selinux	selinuxfs	defaults	0	0

2.d. Configurer Baselayout

SELinux ne supporte pas Devfs. Vous devez configurer Baselayout afin qu'il utilise soit une arborescence statique de fichiers de périphériques, soit udev. Si vous souhaitez utiliser udev, l'archivage des fichiers périphériques doit être désactivé. Éditez le fichier /etc/conf.d/rc. Mettez RC_DEVICES à static ou udev et RC_DEVICE_TARBALL à no. Si vous avez des fichiers de périphériques personnalisés, static est suggéré, sinon udev.

Exemple de code 4.1 : Configuration des scripts d'initialisation

# Use this variable to control the /dev management behavior.
#  auto   - let the scripts figure out what's best at boot
#  devfs  - use devfs (requires sys-fs/devfsd)
#  udev   - use udev (requires sys-fs/udev)
#  static - let the user manage /dev

RC_DEVICES="udev"

# UDEV OPTION:
# Set to "yes" if you want to save /dev to a tarball on shutdown
# and restore it on startup.  This is useful if you have a lot of
# custom device nodes that udev does not handle/know about.

RC_DEVICE_TARBALL="no"

2.e. Redémarrage

Nous devons créer quelques répertoires avant de redémarrer.

Exemple de code 5.1 : Créer les répertoires nécessaires

# mkdir /selinux
# mkdir /sys

Maintenant, redémarrez.

3. Installer les outils SELinux

3.a. Installer les paquets SELinux

Installez les bibliothèques, les utilitaires et les politiques de base. La version des politiques peut éventuellement être ajustée, référez-vous à la vue d'ensemble de SELinux pour plus d'informations sur les versions des politiques. Enfin, chargez les politiques.

Exemple de code 1.1 : Installer les paquets et les politiques de base de SELinux

# emerge checkpolicy policycoreutils
# FEATURES=-selinux emerge selinux-base-policy

Note : La partie « FEATURES=-selinux » est nécessaire, pour cette ligne d'installation uniquement, la première fois uniquement. Elle sert à désactiver la fonctionnalité selinux de Portage qui a besoin de policycoreutils et de selinux-base-policy pour fonctionner.

3.b. Choisir le type de politique

Depuis la version 2006.1, les utilisateurs ont maintenant la possibilité de choisir entre une politique stricte ou une politique ciblée.

Avec la politique stricte, tous les processus sont confinés. Si vous êtes familier avec la politique Gentoo SELinux datant d'avant 2006.1, cette politique était stricte. La politique stricte est suggérée pour les serveurs. Gentoo ne supporte pas la politique stricte sur un système de bureau.

La politique ciblée est différente, seuls les processus avec un accès au réseau sont confinés. Gentoo ne supporte les stations de travail qu'avec la politique ciblée. Cette politique peut aussi être utilisée sur des serveurs.

Éditez le fichier /etc/selinux/config pour définir le type de politique.

Exemple de code 2.1 : Contenu de /etc/selinux/config

# This file controls the state of SELinux on the system on boot.

# SELINUX can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - No SELinux policy is loaded.
SELINUX=permissive (Vous devez mettre permissive pour le reste de l'installation.)

# SELINUXTYPE can take one of these two values:
#       targeted - Only targeted network daemons are protected.
#       strict - Full SELinux protection.
SELINUXTYPE=strict (Choisissez strict ou targeted.)

Note : N.D.T. : Ce fichier contrôle l'état de SELinux au démarrage du système. La variable SELINUX peut prendre une des trois valeurs : « enforcing » (la politique de sécurité est respectée), « permissive » (des avertissements sont affichés au lieu de respecter la politique) ou « disabled » (la politique n'est pas chargée). La variable SELINUXTYPE peut prendre une de ces deux valeurs : « targeted » (politique ciblée, seuls les démons ciblés sont protégés) ou « strict » (protection SELinux totale).

3.c. Installer des paquets modifiés pour SELinux

Plusieurs paquets systèmes contiennent des modifications pour SELinux. Ces modifications fournissent diverses fonctionnalités supplémentaires pour SELinux, comme par exemple l'affichage du contexte des fichiers.

Exemple de code 3.1 : Réinstaller des paquets

# emerge sysvinit pam coreutils findutils openssh procps psmisc shadow util-linux python-selinux

Note : S'il s'avère que vous ne puissiez plus utiliser Portage à cause d'une erreur telle que : « !!! 'module' object has no attribute 'secure_rename' or AttributeError: 'module' object has no attribute 'getcontext' », c'est un bogue de Portage dû à l'absence de python-selinux. Installez-le comme ceci pour résoudre le problème : « FEATURES=-selinux emerge python-selinux ». Consultez les commentaires du bogue #122517 pour plus d'informations.

D'autres paquets disposent de modifications pour SELinux, mais ils sont optionnels. Les paquets suivants doivent être réinstallés s'ils sont déjà présents sur le système, afin que les modifications concernant SELinux soient appliquées :

  • app-admin/logrotate
  • sys-apps/fcron
  • sys-apps/vixie-cron
  • sys-fs/device-mapper
  • sys-fs/udev
  • sys-libs/pwdb

Note : Fcron et vixie-cron sont les seuls démons cron à supporter SELinux.

3.d. Installer les politiques de sécurité applicatives

À l'avenir, lorsque vous installerez un paquet, la politique de sécurité correspondante sera installée avant, en tant que dépendance. Mais pour le moment, dans notre processus de conversion du système, il nous reste à installer les politiques applicatives des paquets que l'on a déjà installés. Selinux-base-policy comprend déjà les politiques de la majorité des paquets du profil system.

Regardez dans le répertoire /usr/portage/sec-policy, chaque entrée correspond à une politique. La convention de nommage est selinux-NOMPAQUET, où NOMPAQUET est le nom du paquet auquel est associée la politique de sécurité. Par exemple, le paquet selinux-apache est le paquet qui contient la politique de sécurité SELinux pour le paquet net-www/apache. Installez chacune des politiques désirées et chargez-les. Si vous installez une station de travail, n'oubliez pas le paquet selinux-desktop.

Exemple de code 4.1 : Exemple d'installation des politiques de sécurité pour Apache et BIND

# ls /usr/portage/sec-policy
(Liste des répertoires...)

# emerge selinux-apache selinux-bind

3.e. Étiqueter les systèmes de fichiers

Maintenant, étiquetez les systèmes de fichiers. Cela assigne une étiquette de sécurité à chaque fichier contenu dans le système de fichiers. Il est important de garder ces étiquettes dans un état cohérent.

Exemple de code 5.1 : Étiqueter les systèmes de fichiers

# rlpkg -a -r

Attention : Un bogue connu dans les anciennes versions de Grub empêche ce dernier de lire les liens symboliques qui ont été étiquetés. Utilisez au minimum la version 0.94 de Grub et réinstallez-le dans le secteur d'amorçage (MBR) pour vous assurez d'utiliser la bonne version du code. Au cas où... vous avez bien un LiveCD sous la main, n'est-ce pas ?

Exemple de code 5.2 : Réinstaller Grub dans le secteur d'amorçage

# grub

grub> root (hd0,0) (Votre partition contenant /boot.)
grub> setup (hd0) (Où sera installé Grub. Ici dans le secteur d'amorçage.)

3.f. Redémarrage final

Redémarrez, connectez-vous, puis ré-étiquetez tous les fichiers encore une fois pour vous assurez que tous les fichiers sont étiquetés (certains fichiers ont pu être créés pendant l'arrêt et le redémarrage du système).

Exemple de code 6.1 : Ré-étiquetez

# rlpkg -a -r

Note : Il vous est fortement suggéré de vous inscrire à la liste de diffusion gentoo-hardened. Il y a généralement peu de trafic et les annonces concernant SELinux y sont diffusées.

SELinux est maintenant installé !

C. Utiliser SELinux

1. Présentation de SELinux

1.a. Les types SELinux

Un type SELinux est un attribut de sécurité assigné à un objet (un fichier, un port réseau, etc.). Le type d'un processus est communément appelé son domaine. Une politique de sécurité SELinux est principalement constituée de règles pour respecter les types, qui décrivent de quelles manières les domaines sont autorisés à interagir avec les objets et avec les autres domaines. Un type est généralement suffixé par « _t », par exemple : sysadm_t. Le type est l'attribut le plus important pour un processus ou un objet, car la plupart des décisions politiques se basent sur les types sources et cibles.

1.b. Les rôles SELinux

La sécurité fournie par SELinux tourne autour des types. Les rôles SELinux sont donc différents de ce que l'on peut trouver dans un système de contrôle d'accès basé sur les rôles (RBAC). Les différentes autorisations ne sont pas attribuées aux rôles. Un rôle décrit l'ensemble des types dont un utilisateur peut se servir. Par exemple, un administrateur qui utilise un système pour exécuter des tâches d'utilisateur classique devrait être dans le rôle staff_r. S'il veut procéder à une tâche d'administration système, il doit alors explicitement basculer dans le rôle sysadm_r. En termes SELinux, la liste des domaines dans lesquels un utilisateur peut se trouver dépend de son rôle. Si un rôle n'est pas autorisé à avoir un certain domaine, une transition vers ce domaine sera rejetée, même si la règle du type permet la transition de domaine. Un rôle est généralement suffixé par un « _r », par exemple : system_r.

1.c. Les identités SELinux

Qu'est-ce qu'une identité SELinux ?

Une identité SELinux est similaire à un nom d'utilisateur Linux. Le changement d'identité devrait être limité à certains cas spécifiques, car le contrôle d'accès basé sur les rôles se repose sur l'identité SELinux. Donc, en général, l'identité SELinux d'un utilisateur ne changera pas tout au long de sa session. L'identifiant utilisateur de Linux peut être changé par set(e)uid, ce n'est donc pas un identifiant approprié pour une identité SELinux. Si on attribue une identité SELinux à un utilisateur, celle-ci doit correspondre au nom d'utilisateur Linux. À chaque identité SELinux on attribue un ensemble de rôles.

Configurer la correspondance des identités SELinux

Une politique SELinux contient plusieurs identités SELinux génériques qui devraient convenir pour tous les utilisateurs. Cette correspondance n'a besoin d'être configurée que lors d'une utilisation de la politique stricte. Vous n'avez pas besoin de la configurer avec la politique ciblée, car l'identité par défaut (user_u) est suffisante dans tous les cas.

Lorsqu'un utilisateur se connecte, l'identité SELinux est déterminée selon cette correspondance.

Identité SELinux Rôles Description
system_u system_r Pour les processus systèmes (non-interactifs). Ne devrait pas être attribuée à un utilisateur.
user_u user_r Pour les utilisateurs sans privilège. La correspondance par défaut.
staff_u staff_r, sysadm_r Pour les administrateurs systèmes qui se connectent également pour exécuter des tâches d'utilisateur normal.
sysadm_u sysadm_r Pour les administrateurs systèmes qui ne font que se connecter pour exécuter des tâches administratives. Il est suggéré de ne pas utiliser cette identité.
root staff_r, sysadm_r Identité spéciale pour root. Les autres utilisateurs devraient plutôt utiliser staff_u à la place.

Pour savoir comment utiliser semanage afin de configurer vos correspondances, lisez notre Guide pratique SELinux.

1.d. Les contextes SELinux

L'utilisation des trois modèles de sécurité précédents ensemble s'appelle un contexte SELinux et se note sous la forme : identité:rôle:type. Le contexte SELinux est la valeur la plus importante dans la décision d'un accès.

Le contexte objet

Un ls -Z typique peut renvoyer un résultat semblable à celui-ci :

Exemple de code 4.1 : Exemple de ls -Z

drwxr-xr-x  root     root     system_u:object_r:bin_t          bin
drwxr-xr-x  root     root     system_u:object_r:boot_t         boot
drwxr-xr-x  root     root     system_u:object_r:device_t       dev
drwxr-xr-x  root     root     system_u:object_r:etc_t          etc

Les trois premières colonnes décrivent les permissions, le nom d'utilisateur et le nom de groupe, valeurs typiques de Linux. La quatrième colonne est le contexte du fichier ou du répertoire. On donne le rôle générique object_r aux objets. Des deux autres champs du contexte, on en déduit que les fichiers ont l'identité système et qu'ils sont de types différents, bin_t, boot_t, device_t, et etc_t.

Le contexte processus

Un ps ax -Z typique peut renvoyer ce genre de résultat :

Exemple de code 4.2 : Exemple de ps ax -Z

  PID CONTEXT                                  COMMAND
    1 system_u:system_r:init_t                 [init]
    2 system_u:system_r:kernel_t               [keventd]
    3 system_u:system_r:kernel_t               [ksoftirqd_CPU0]
    4 system_u:system_r:kernel_t               [kswapd]
    5 system_u:system_r:kernel_t               [bdflush]
    6 system_u:system_r:kernel_t               [kupdated]
  706 system_u:system_r:syslogd_t              [syslog-ng]
  712 system_u:system_r:httpd_t                [apache]
  791 system_u:system_r:sshd_t                 [sshd]
  814 system_u:system_r:crond_t                [cron]
  826 system_u:system_r:getty_t                [agetty]
  827 system_u:system_r:getty_t                [agetty]
  828 system_u:system_r:getty_t                [agetty]
  829 system_u:system_r:getty_t                [agetty]
  830 system_u:system_r:getty_t                [agetty]
  831 system_u:system_r:httpd_t                [apache]
  832 system_u:system_r:httpd_t                [apache]
  833 system_u:system_r:httpd_t                [apache]
23093 system_u:system_r:sshd_t                 [sshd]
23095 user_u:user_r:user_t                     [bash]
23124 system_u:system_r:sshd_t                 [sshd]
23126 user_u:user_r:user_t                     [bash]
23198 system_u:system_r:sshd_t                 [sshd]
23204 user_u:user_r:user_t                     [bash]
23274 system_u:system_r:sshd_t                 [sshd]
23275 pebenito:staff_r:staff_t                 [bash]
23290 pebenito:staff_r:staff_t                 ps ax -Z

Dans cet exemple, le contexte de chaque processus est affiché en plus des informations typiques. Si on examine cette liste, on remarque que tous les processus du noyau et les démons tournent sous l'identité system_u et avec le rôle system_r. Les domaines individuels dépendent du programme. On note plusieurs utilisateurs connectés en SSH, sous l'identité générique user_u. Enfin, un utilisateur, portant l'identité pebenito, est connecté avec le rôle staff_r et se trouve dans le domaine staff_t.

1.e. Les fichiers de politiques de SELinux

Les fichiers sources des politiques de SELinux ne sont plus installés sur le système. Dans les répertoires /usr/share/selinux/{strict,targeted}, vous trouverez une série de paquets de politiques et d'en-têtes afin de construire des modules locaux. Les fichiers de politiques sont traités par m4, puis le compilateur de politique checkmodule vérifie qu'il n'y ait pas d'erreur de syntaxe avant de créer un module de politique. Ensuite, un paquet de politique est créé avec la commande semodule_package en utilisant le module de politique et les contextes de fichiers du module. La politique, une fois empaquetée, peut alors être chargée dans un noyau SELinux en l'insérant dans le magasin de modules.

*.pp

Les paquets de politiques pour cette politique. Ils doivent être insérés dans le magasin de modules afin d'être chargés dans la politique. Dans le paquet, se trouve un module de politique chargeable et éventuellement un fichier de contexte de fichier.

include/

Les en-têtes de politiques pour cette politique.

1.f. Les versions de politiques binaires

Lors d'une compilation de politique, le fichier binaire résultant contient un numéro de version. La première version qui a été introduite dans le noyau Linux a été la version 15. Le numéro de version n'est en général incrémenté que lorsqu'une nouvelle fonctionnalité ajoutée nécessite des changements de structure de la politique compilée binaire. Par exemple, dans Linux 2.6.5, des extensions concernant les politiques conditionnelles ont été ajoutées. Le numéro de version des politiques résultantes a été incrémenté à 16.

Quelle est la version de politique de mon noyau ?

La version de politique d'un noyau peut se déterminer à l'aide des outils sestatus ou policyvers. Les noyaux actuels peuvent charger une politique d'une version antécédente, par exemple un noyau en version 17 peut aussi charger les politiques en version 16. Cependant, cette compatibilité pourra être supprimée à l'avenir.

Note : L'infrastructure de gestion des politiques (libsemanage) créera et utilisera automatiquement la bonne version de la politique. Aucune étape supplémentaire n'est requise.

Versions de politiques

La table suivante indique l'historique des versions de politiques selon la version de Linux 2.6.

Version Description Versions de Linux
12 SELinux « Vieille API » (obsolète)
15 SELinux « nouvelle API » intégrée dans 2.6 2.6.0 - 2.6.4
16 Ajout d'extensions permettant les politiques conditionnelles 2.6.5
17 Ajout du support IPv6 2.6.6 - 2.6.7
18 Amélioration du support des sockets Netlink 2.6.8 - 2.6.11
19 Amélioration de la sécurité multi-niveaux 2.6.12 - 2.6.13
20 Optimisation de la taille des tables de vecteurs d'accès 2.6.14 - 2.6.18
21 Classes d'objets 2.6.19 - 2.6.24
22 Fonctionnalités des politiques Depuis 2.6.25

1.g. Les extensions de politique conditionnelle

Les extensions de politique conditionnelle permettent l'activation et la désactivation de règles à la volée, sans besoin de recharger une politique modifiée. En utilisant les booléens et les expressions de politique, les règles peuvent être appliquées conditionnellement.

Afficher les valeurs des booléens

L'état des booléens de la politique courante peut être déterminé de deux façons. Premièrement, en utilisant sestatus :

Exemple de code 7.1 : Exemple de résultat de sestatus

# sestatus
SELinux status:         enabled
SELinuxfs mount:        /selinux
Current mode:           enforcing
Policy version:         17
 
Policy booleans:
user_ping               inactive

La deuxième méthode est l'utilisation de getsebool, un outil simple qui affiche l'état courant et l'état en attente (pending) des booléens.

Exemple de code 7.2 : Exemple de résultat de getsebool

# getsebool -a
user_ping --> active: 0 pending: 0

Modifier un booléen

La valeur d'un booléen peut être inversée en utilisant la commande togglesebool. On peut spécifier plusieurs booléens sur la ligne de commande. La nouvelle valeur des booléens sera affichée en retour.

Exemple de code 7.3 : Exemple d'utilisation de togglesebool

# togglesebool user_ping
user_ping: active

La valeur d'un booléen peut également être définie explicitement avec setsebool.

Exemple de code 7.4 : Exemple d'utilisation de setsebool

# setsebool user_ping 0

Pour définir la valeur d'un booléen et en faire sa valeur par défaut, utilisez l'option -P.

Exemple de code 7.5 : Changer la valeur par défaut

# setsebool -P user_ping 1

1.h. Les messages du noyau concernant la politique

Lorsque le système tourne, un programme ou un utilisateur peut tenter de faire quelque chose qui viole la politique de sécurité. Si le système respecte la politique (mode enforcing), l'accès sera refusé et un message sera envoyé dans le journal du noyau. Si le système est en mode permissive, l'accès sera autorisé mais il y aura tout de même un message envoyé au journal du noyau.

Les messages de l'AVC

La plupart des messages du noyau provenant de SELinux viennent du cache de vecteurs d'accès (AVC pour Access Vector Cache). Comprendre les refus d'accès est important pour déterminer si une attaque est en cours ou bien si le programme demande un accès non prévu. Voici un exemple de refus d'accès :

Exemple de code 8.1 : Exemple de message de l'AVC

avc:  denied  { read write } for  pid=3392 exe=/bin/mount dev=03:03 ino=65554
scontext=pebenito:sysadm_r:mount_t tcontext=system_u:object_r:tmp_t tclass=file

Bien que la plupart des messages de l'AVC soient des refus d'accès, il peut aussi de temps en temps y avoir des messages d'audit à propos d'accès autorisés :

Exemple de code 8.2 : Un autre exemple de message de l'AVC

avc:  granted  { load_policy } for  pid=3385 exe=/usr/sbin/load_policy
scontext=pebenito:sysadm_r:load_policy_t tcontext=system_u:object_r:security_t tclass=security

Dans ce cas-ci, la demande de charger la politique a été autorisée. C'est un évènement de sécurité critique et est donc toujours audité. Un autre évènement toujours audité est le passage du mode enforcing vers permissive et inversement.

SELinux n'enregistrera pas les refus d'accès dans le journal s'il y en a trop à la fois. Cela ne veut pas forcément dire qu'une attaque est en cours. Un programme peut par exemple être en train d'exécuter un stat() sur les fichiers présents dans /dev/. SELinux limite le nombre de messages afin de minimiser les risques de saturation du journal :

Exemple de code 8.3 : Un dernier exemple de message de l'AVC

AVC: 12 messages suppressed.

Si le comportement du programme est normal et que ces accès doivent bien être refusés, la politique doit alors être modifiée afin de ne pas auditer ces accès.

Autres messages du noyau

Exemple de code 8.4 : inode_doinit_with_dentry

inode_doinit_with_dentry:  context_to_sid(system_u:object_r:bar_t) returned 22 for dev=hda3 ino=517610

Cela signifie que le fichier se trouvant sur /dev/hda3 et ayant le numéro d'inode 517610 a le contexte system_u:object_r:bar_t, qui est invalide. Les objets qui ont un contexte invalide sont traités comme s'ils avaient le contexte system_u:object_r:unlabeled_t.

1.i. Autopsie d'un refus d'accès

Les refus d'accès contiennent une quantité variable d'information, selon le type d'accès.

Exemple de code 9.1 : Exemples de refus d'accès

avc:  denied  { lock } for  pid=28341 exe=/sbin/agetty path=/var/log/wtmp dev=03:03 ino=475406
scontext=system_u:system_r:getty_t tcontext=system_u:object_r:var_log_t tclass=file

avc:  denied  { create } for  pid=20909 exe=/bin/ls scontext=pebenito:sysadm_r:mkinitrd_t
tcontext=pebenito:sysadm_r:mkinitrd_t tclass=unix_stream_socket

avc:  denied  { setuid } for  pid=3170 exe=/usr/bin/ntpd capability=7
scontext=system_u:system_r:ntpd_t tcontext=system_u:system_r:ntpd_t tclass=capability

Les refus d'accès concernent généralement l'accès à un fichier. Pour mieux comprendre, décortiquons ici le premier message :

Extrait Explication
avc: denied SELinux a refusé l'accès.
{ lock } La tentative d'accès est de type « lock » (verrou).
pid=28341 L'identifiant du processus est 28341.
exec=/sbin/agetty Le chemin complet du processus exécutable est /sbin/agetty.
path=/var/log/wtmp Le chemin complet de l'objet cible est /var/log/wtmp. Notez que le chemin complet n'est pas toujours disponible.
dev=03:03 L'objet cible réside sur le périphérique 03:03 (numéros majeur:mineur). Le noyau 2.6 peut procéder à une résolution de nom, hda3 ici.
ino=475406 Le numéro d'inode de la cible est 475406.
scontext=system_u:system_r:getty_t Le contexte du programme est system_u:system_r:getty_t.
tcontext=system_u:object_r:var_log_t Le contexte de l'objet cible est system_u:object_r:var_log_t.
tclass=file L'objet cible est un fichier normal.

Tous les messages de l'AVC n'ont pas forcément tous ces champs, comme notamment les deux exemples suivants. Les champs présents varient en fonction de la classe de l'objet cible. Cependant, les champs les plus importants (le type d'accès, les contextes source et cible et l'objet cible) seront toujours affichés dans un message de l'AVC.

Comprendre le refus d'accès

Les messages de refus d'accès sont parfois trompeurs car ils peuvent être envoyés pour plusieurs raisons. Pour comprendre ce qu'il se passe, il faut connaitre le comportement du programme et savoir correctement interpréter les messages de refus d'accès. La cible n'est pas forcément un fichier, mais peut aussi être une socket réseau, une communication interprocessus, etc.

Dans l'exemple précédent, agetty se voit refuser le droit de poser un verrou sur un fichier. Le type du fichier est var_log_t, ce qui implique que le fichier cible se trouve dans /var/log/. Grâce aux informations supplémentaires fournies par le champ path= du message de refus d'accès, on confirme que le fichier est /var/log/wtmp. Si l'information du chemin complet n'avait pas été disponible, on aurait pu trouver le fichier avec le numéro d'inode. wtmp est un fichier qui contient des informations à propos des utilisateurs actuellement connectés au système et agetty gère justement les connexions depuis un tty. On peut donc en conclure que c'est un comportement normal de la part d'agetty de vouloir mettre à jour wtmp. Cependant, pourquoi cet accès est-il refusé ? Y aurait-il une anomalie dans la politique qui empêcherait agetty de mettre à jour wtmp ? En réalité, c'est wtmp qui a un mauvais contexte. Cela devrait être system_u:object_r:wtmp_t et non pas system_u:object_r:var_log_t.

Si cette demande d'accès n'avait pas été bien comprise, l'administrateur aurait pu faire l'erreur d'autoriser les accès en lecture/écriture de getty_t vers les fichiers var_log_t, ce qui aurait été incorrect, puisqu'agetty n'a besoin que de modifier /var/log/wtmp. Cet exemple souligne à quel point il est important de garder les contextes des fichiers dans un état cohérent.

1.j. Références

Le site de SELinux et le fichier README de SELinux.

2. Guide SELinux

2.a. Charger une politique dans un noyau SELinux

Vous devez vous placer dans le rôle sysadm_r.

Exemple de code 1.1 : La commande semodule

# semodule -B

2.b. Changer de rôle

Votre utilisateur doit avoir accès au rôle cible. Dans cet exemple, nous nous mettons dans le rôle sysadm_r.

Exemple de code 2.1 : La commande newrole

# newrole -r sysadm_r

2.c. Spécifier les rôles disponibles pour un utilisateur

Il y a une correspondance entre les utilisateurs Linux et les identités SELinux. La politique dispose d'utilisateurs SELinux génériques selon les configurations des rôles. Par exemple, pour associer l'utilisateur pebenito à l'identité SELinux staff_u :

Exemple de code 3.1 : Associer pebenito à staff_u

# semanage login -a -s staff_u pebenito

La politique n'a pas besoin d'être rechargée. Si l'utilisateur est connecté, il doit simplement se reconnecter afin que les changements soient pris en compte.

2.d. Ré-étiqueter les systèmes de fichiers

Vous devez vous placer dans le rôle sysadm_r.

Exemple de code 4.1 : Ré-étiqueter

# rlpkg -a

2.e. Ré-étiqueter un paquet individuel

En plus de pouvoir ré-étiqueter des systèmes de fichiers entiers, vous pouvez aussi ré-étiqueter des paquets de Portage individuellement. Pour cela, vous devez vous placer dans le rôle sysadm_r.

Exemple de code 5.1 : Exemple de rlpkg

# rlpkg shadow sash

On utilise le script rlpkg avec un nombre quelconque de noms de paquets comme arguments.

2.f. Chercher les bibliothèques qui utilisent les relocations de textes

SELinux contient des protections améliorées de la mémoire. Une des fonctionnalités supportées et d'autoriser les relocations de textes ELF. Les bibliothèques avec des relocations de textes ont une étiquette spéciale et l'outil rlpkg possède une option pour rechercher ces bibliothèques.

Exemple de code 6.1 : Chercher les TEXTREL

# rlpkg -t

Cela sera également effectué après un ré-étiquetage complet.

2.g. Démarrer les démons dans le bon domaine

Contrôler les démons qui possèdent des scripts d'initialisation dans /etc/init.d est très légèrement différent avec SELinux. La commande run_init doit être utilisée pour lancer les scripts, afin de s'assurer qu'ils soient exécutés dans le bon domaine. La commande est identique, excepté qu'elle est préfixé par run_init. Vous devez être dans le rôle sysadm_r.

Exemple de code 7.1 : Exemples d'utilisation de run_init

# run_init /etc/init.d/ntpd start
# run_init /etc/init.d/apache2 restart
# run_init /etc/init.d/named stop

Intégration de run_init dans Gentoo

run_init a été intégré dans le système de scripts d'initialisation de Gentoo. Avec SELinux installé, les services peuvent être démarrés et arrêtés comme d'habitude, sauf que maintenant ils authentifieront l'utilisateur.

Exemple de code 7.2 : Exemple avec run_init une fois intégré

# /etc/init.d/sshd restart
Authenticating root.
Password:
 * Stopping sshd...                       [ ok ]
 * Starting sshd...                       [ ok ]

2.h. Basculer entre les modes enforcing et permissive

Basculer entre les différents modes de SELinux est très simple. Envoyez 1 pour enforcing ou 0 pour permissive au fichier /selinux/enforce pour définir le mode. En lisant le contenu du fichier, vous obtiendrez le mode courant. Si l'option du noyau « NSA SELinux Development Support » est désactivée, le système sera toujours en mode enforcing et ne pourra pas être passé en mode permissive.

Exemple de code 8.1 : Lire et régler le mode enforce

(Lire le mode courant.)
# cat /selinux/enforce
(Passer en mode enforcing.)
# echo 1 > /selinux/enforce
(Passer en mode permissive.)
# echo 0 > /selinux/enforce

Une machine dont le support du développement a été activé dans le noyau peut être démarrée en mode enforcing en spécifiant l'option enforcing=1 sur la ligne de commande de démarrage du noyau dans le chargeur de démarrage (Grub, LILO, etc.).

Définir le mode au démarrage

En sus des options du noyau mentionnées précédemment, le mode de démarrage peut être défini dans le fichier /etc/selinux/config.

Exemple de code 8.2 : /etc/selinux/config

# SELINUX can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - No SELinux policy is loaded.
SELINUX=permissive

Le réglage défini dans ce fichier sera écrasé par la valeur donnée en argument du noyau décrite précédemment.

2.i. Comprendre le retour de la commande sestatus

L'outil sestatus nous permet de récupérer des informations détaillées à propos des spécificités de SELinux. L'option -v nous fournit des détails supplémentaires à propos des contextes des processus et des fichiers. Le résultat de la commande est divisé en quatre sections. Sestatus ne donne des informations complètes qu'à un utilisateur connecté en root ou bien se trouvant dans le rôle sysadm_r.

Exemple de code 9.1 : Exemple de rapport sestatus

SELinux status:         enabled
SELinuxfs mount:        /selinux
Current mode:           enforcing
Policy version:         18

Les informations principales du rapport sont fournies dans la première section. La première ligne montre si les fonctions du noyau SELinux existent et sont activées. Si le statut est désactivé (disabled), soit le noyau n'a pas le support SELinux, soit la politique n'est pas chargée. La seconde ligne montre le point de montage du système de fichiers SELinux. Lors d'une utilisation normale, ce sera /selinux. La troisième ligne montre le mode SELinux courant, soit enforcing, soit permissive. La quatrième ligne montre la version de la base de données de la politique supportée par le noyau actuel.

Exemple de code 9.2 : Quelques booléens

Policy booleans:
secure_mode             inactive
ssh_sysadm_login        inactive
user_ping               inactive

La seconde section affiche l'état des booléens concernant la politique. La colonne de gauche contient le nom du booléen et celle de droite son état : active ou inactive. Cette section n'existe pas avec les noyaux en version 15.

Exemple de code 9.3 : Exemple de contextes de processus

Process contexts:
Current context:        pebenito:sysadm_r:sysadm_t
Init context:           system_u:system_r:init_t
/sbin/agetty            system_u:system_r:getty_t
/usr/sbin/sshd          system_u:system_r:sshd_t

La troisième section affiche les contextes des processus courants ainsi que de quelques processus importants. Si un processus est exécuté dans un contexte incorrect, il ne fonctionnera pas correctement.

Exemple de code 9.4 : Exemple de contextes de fichiers

File contexts:
Controlling term:       pebenito:object_r:sysadm_devpts_t
/sbin/init              system_u:object_r:init_exec_t
/sbin/agetty            system_u:object_r:getty_exec_t
/bin/login              system_u:object_r:login_exec_t
/sbin/rc                system_u:object_r:initrc_exec_t
/sbin/runscript.sh      system_u:object_r:initrc_exec_t
/usr/sbin/sshd          system_u:object_r:sshd_exec_t
/sbin/unix_chkpwd       system_u:object_r:chkpwd_exec_t
/etc/passwd             system_u:object_r:etc_t
/etc/shadow             system_u:object_r:shadow_t
/bin/sh                 system_u:object_r:bin_t -> system_u:object_r:shell_exec_t
/bin/bash               system_u:object_r:shell_exec_t
/bin/sash               system_u:object_r:shell_exec_t
/usr/bin/newrole        system_u:object_r:newrole_exec_t
/lib/libc.so.6          system_u:object_r:lib_t -> system_u:object_r:shlib_t
/lib/ld-linux.so.2      system_u:object_r:lib_t -> system_u:object_r:shlib_t

La quatrième section affiche les contextes du terminal contrôlant le processus courant ainsi que de quelques fichiers importants. Pour les liens symboliques, le contexte du lien ainsi que celui de la cible de celui-ci sont affichés. Si un fichier a un contexte incorrect, le fichier peut être inaccessible ou posséder des permissions incorrectes par rapport à un processus en particulier.

3. Foire aux Questions sur SELinux

3.a. Limites de SELinux

Est-ce que SELinux permet de limiter les ressources systèmes ?

Non, la limitation de ressource n'est pas dans le domaine d'un système de contrôle d'accès. Si vous cherchez ce type de fonctionnalités, orientez-vous plutôt vers GRSecurity et RSBAC.

3.b. SELinux et les autres projets Hardened

Puis-je utiliser SELinux et GRSecurity (et PaX) ?

Oui, SELinux peut être utilisé avec GRSecurity et/ou PaX sans problème. Par contre, nous vous suggérons de ne pas utiliser GRACL puisqu'il serait redondant avec le contrôle d'accès de SELinux.

Puis-je utiliser SELinux avec le compilateur Hardened (PIE-SSP) ?

Oui. De plus, nous vous recommandons d'utiliser PaX pour tirer profit au maximum des fonctionnalités PIE du compilateur.

Puis-je utiliser SELinux avec RSBAC ?

Aucune idée. Tenez-nous au courant si vous essayez...

3.c. SELinux et les systèmes de fichiers

Puis-je utiliser SELinux sur mon système de fichiers ?

SELinux est utilisable sur de l'ext2, ext3, JFS et XFS. Reiserfs (reiser3) dispose des attributs étendus mais l'implémentation n'a jamais été terminée et ne fonctionne plus depuis 2.6.14. Reiser4 n'est pas supporté.

Et sur les autres systèmes de fichiers ?

SELinux peut également monter les systèmes de fichiers annexes, tels que vfat et iso9660, mais avec une grosse restriction : tous les fichiers du montage auront le même type SELinux, puisque le système de fichiers ne supporte pas les attributs étendus. Tmpfs est le seul système de fichiers annexe à supporter les attributs étendus.

Puis-je utiliser SELinux sur un montage réseau ?

Oui, SELinux peut monter les systèmes de fichiers en réseau, tels que NFS et CIFS, mais avec la même restriction : tous les fichiers du montage auront le même type SELinux, puisque le système de fichiers ne supporte pas les attributs étendus. Espérons que les systèmes de fichiers en réseau pourront gérer les attributs étendus dans un avenir proche.

3.d. Messages d'erreur de Portage

emerge se plaint de ne pas trouver un module SELinux

Exemple de code 4.1 : Message de Portage

!!! SELinux module not found. Please verify that it was installed.

Ce message indique que le module SELinux pour Portage est manquant ou endommagé. Ce peut aussi être Python qui a été mis à jour vers une nouvelle version, ce qui nécessite la recompilation de python-selinux. Réinstallez dev-python/python-selinux. Si des paquets ont été installés avec cette erreur, ils doivent être ré-étiquetés une fois que le problème est résolu. En cas de doute sur les paquets à ré-étiqueter, ré-étiquetez tout.

3.e. Messages d'erreur du noyau à propos de SELinux

Lors du démarrage, j'obtiens une erreur register_security

Exemple de code 5.1 : Message du noyau

There is already a security framework initialized, register_security failed.
Failure registering capabilities with the kernel
selinux_register_security:  Registering secondary module capability
Capability LSM initialized

Cela signifie que le module Capability LSM n'a pas pu s'enregistrer en tant que module principal, puisque SELinux l'est déjà. Le troisième message signifie qu'il s'est enregistré avec SELinux comme un module secondaire. C'est normal.

3.f. Messages d'erreur de setfiles

Le ré-étiquetage échoue à cause d'un contexte invalide

Exemple de code 6.1 : Exemple de contextes invalides

# make relabel
/usr/sbin/setfiles file_contexts/file_contexts `mount | awk '/(ext[23]| xfs).*rw/{print $3}'`
/usr/sbin/setfiles:  read 559 specifications
/usr/sbin/setfiles:  invalid context system_u:object_r:default_t on line number 39
/usr/sbin/setfiles:  invalid context system_u:object_r:urandom_device_t on line number 120
/usr/sbin/setfiles:  invalid context system_u:object_r:fonts_t on line number 377
/usr/sbin/setfiles:  invalid context system_u:object_r:fonts_t on line number 378
/usr/sbin/setfiles:  invalid context system_u:object_r:krb5_conf_t on line number 445
/usr/sbin/setfiles:  invalid context system_u:object_r:system_cron_spool_t on line number 478
/usr/sbin/setfiles:  invalid context system_u:object_r:system_cron_spool_t on line number 479
/usr/sbin/setfiles:  invalid context system_u:object_r:system_cron_spool_t on line number 492
/usr/sbin/setfiles:  invalid context system_u:object_r:system_cron_spool_t on line number 493
/usr/sbin/setfiles:  invalid context system_u:object_r:system_cron_spool_t on line number 494
Exiting after 10 errors.
make: *** [relabel] Error 1

Commencez par vérifier que /selinux soit bien monté, car sinon setfiles ne peut pas valider de contexte et croira que tous les contextes sont invalides. Si /selinux est monté, alors il est probable qu'une nouvelle politique n'ait pas encore été chargée et donc les contextes ne soient pas encore valides.

4. L'infrastructure de gestion de SELinux

4.a. L'infrastruction de gestion de SELinux

L'infrastructure de gestion de SELinux s'occupe de plusieurs aspects des politiques SELinux. Ces outils de gestion sont basés sur la bibliothèque centrale libsemanage. Plusieurs programmes de gestion permettent d'achever plusieurs tâches, dont notamment semanage et semodule. Ils vous permettront de configurer certains aspects sans avoir besoin de la source de la politique.

4.b. Gestion des modules de politiques SELinux

Qu'est-ce qu'un module de politique ?

SELinux gère les politiques modulaires. Cela consiste en plusieurs morceaux de politiques qui sont assemblés pour former une politique à charger dans le noyau. La structure est assez similaire au noyau lui-même et à ses modules : une image principale du noyau est chargée, puis plusieurs modules du noyau peuvent être ajoutés (à condition que leurs dépendances soient satisfaites) et supprimés, à chaud, sans redémarrer le système. De même, chaque politique est constituée d'un module de base et d'un nombre éventuellement nul de modules de politiques qui forment la politique. Les modules sont construits en compilant un morceau de politique et en créant un paquet de politique (*.pp) contenant la politique compilée et éventuellement des contextes de fichiers.

Le paquet du module de base (base.pp) contient le strict nécessaire de la politique. Toutes les politiques modulaires doivent au moins avoir leur module de base. Dans Gentoo, nous avons rajouté dans ce paquet des politiques pour toutes les parties du profil système. Il est installé par l'ebuild selinux-base-policy. Les autres ebuilds dans Portage contiennent un ou plusieurs modules de politiques.

Pour plus d'informations à propos de l'écriture d'un module de politique, en particulier pour pouvoir personnaliser une politique, veuillez consulter le guide des modules de politiques.

Le magasin de modules SELinux

Lorsqu'un module de politique est inséré ou supprimé, les modules sont copiés depuis ou supprimé du magasin de modules. Ce dépôt contient une copie des modules qui ont été utilisés pour créer la politique courante, ainsi que plusieurs fichiers annexes. Ce dépôt se trouve dans /etc/selinux/{strict,targeted}/modules. Vous ne devrez jamais avoir besoin d'accéder à ces fichiers directement. Un outil basé sur libsemanage devrait s'en occuper pour vous.

Libsemanage manipule le magasin de modules à l'aide de transaction. Cela signifie que si un ensemble d'opérations (une transaction) sont exécutées sur le magasin et qu'une partie échoue, alors la transaction entière est annulée. Cela empêche le magasin de se retrouver dans un état incohérent.

La gestion du magasin de modules passe par la commande semodule. L'option -l permet d'en lister son contenu.

Exemple de code 2.1 : Lister le contenu du magasin

# semodule -l
distcc  1.1.1

Puisque le module de base est requis dans tous les cas et qu'il n'a pas de version, il n'est pas affiché dans la liste. Tous les autres modules sont affichés avec leur version.

Ajouter un module de politique

Le module est référencé par son nom.

Exemple de code 2.2 : Insérer un module

# semodule -i module.pp

Cela insérera le module dans le magasin de la politique actuellement configurée, comme spécifié dans /etc/selinux/config. Si l'insertion réussit, la politique sera chargée, sauf si l'option -n est spécifiée. Pour charger le module dans un autre magasin de modules, utilisez l'option -s.

Exemple de code 2.3 : Insérer un module dans un autre magasin

# semodule -s targeted -i module.pp

Puisque nous spécifions un autre magasin, la politique ne sera pas chargée.

Retirer un module de politique

Le module est référencé par son nom dans le magasin de modules.

Exemple de code 2.4 : Supprimer un module

# semodule -r module

Cela supprimera le module du magasin de la politique courante, spécifiée dans /etc/selinux/config. Si la suppression a marché, la politique sera rechargée, sauf si l'option -n a été spécifiée. L'option -s fonctionne également pour une suppression de module.

4.c. Configurer les associations d'identifiants d'utilisateurs

La méthode actuelle pour assigner des ensembles de rôles à un utilisateur est de mettre en place une liste d'associations entre les utilisateurs Linux et les identités SELinux. Lorsqu'un utilisateur se connecte, le programme login utilisera cette liste pour associer la bonne identité SELinux à l'utilisateur. S'il n'y a pas d'association pour un utilisateur, on utilise l'entrée __default__.

La gestion des associations entre utilisateurs Linux et identités SELinux est réalisée par semanage.

Exemple de code 3.1 : Associations entre utilisateurs Linux et identités SELinux

# semanage login -l
Login Name                SELinux User

__default__               user_u
root                      root

Ajouter une entrée

Pour faire correspondre l'utilisateur pebenito à l'identité staff_u :

Exemple de code 3.2 : Associer une identité à un utilisateur

# semanage login -a -s staff_u pebenito

La vue d'ensemble de SELinux contient une description des identités disponibles.

Supprimer une entrée

Pour supprimer l'association de l'utilisateur pebenito :

Exemple de code 3.3 : Supprimer l'identité d'un utilisateur

# semanage login -d pebenito

Note : Les associations d'identités spécifiées par la politique (pas par l'infrastructure de gestion) ne peuvent pas être supprimées.

4.d. Configurer les valeurs par défaut des booléens

Le programme setsebool est maintenant un outil utilisant libsemanage. La fonction de base de cet outil est d'assigner une valeur à un booléen. Pourtant, si la machine est redémarrée, les booléens seront tous réinitialisés à la valeur spécifiée dans la politique. Pour configurer une valeur tout en demandant qu'elle soit par défaut dans la politique, utilisez l'option -P.

Exemple de code 4.1 : Configurer les valeurs par défaut des booléens

# setsebool -P fcron_crond 1

La commande précédente définit la valeur du booléen fcron_crond à 1 et définit également cette valeur comme étant celle par défaut.

4.e. Configurer les identités de SELinux

En principe, on n'a pas besoin d'ajouter des identités de SELinux à la politique de sécurité, car les associations identité/login suffisent. Une bonne raison d'ajouter une nouvelle identité serait pour améliorer les audits, car l'identité SELinux apparait directement dans le contexte du message de refus d'accès.

La gestion des identités SELinux est assurée par l'outil semanage.

Exemple de code 5.1 : Lister les identités SELinux

# semanage user -l
SELinux User    SELinux Roles

root            sysadm_r staff_r
staff_u         sysadm_r staff_r
sysadm_u        sysadm_r
system_u        system_r
user_u          user_r

Ajouter une identité SELinux

En plus de lister les rôles de l'identité, il faut spécifier un préfixe. Ce préfixe doit correspondre à un rôle, par exemple staff ou sysadm, et est utilisé pour étiqueter les répertoires racines des utilisateurs. Si le préfixe utilisé est staff, les utilisateurs Linux qui seront associés à cette identité auront leur répertoire racine étiqueté staff_home_dir_t.

Pour ajouter l'identité test_u contenant les rôles staff_r et sysadm_r avec le préfixe staff :

Exemple de code 5.2 : Ajouter une identité SELinux

# semanage user -a -R 'staff_r sysadm_r' -P staff test_u

Note : Pour pouvoir utiliser l'identité, il faut aussi ajouter une association avec un login.

Supprimer une identité SELinux

Pour supprimer l'identité SELinux test_u :

Exemple de code 5.3 : Supprimer une identité SELinux

# semanage user -d test_u

Note : Les identités SELinux créées par la politique (par opposition à celles créées par l'infrastructure de gestion) ne peuvent pas être supprimées.

5. Les modules de politique locale

5.a. Introduction

Ce guide explique comment mettre en place un module de politique permettant l'ajout de règles locales à la politique.

5.b. Préparation

Copiez l'exemple de Makefile depuis le répertoire doc de selinux-base-policy vers le répertoire qui sera utilisé pour la construction de la politique. Il est suggéré d'utiliser /root/. Les endroits dans lesquels semodule peut lire les modules de politique comprennent les répertoires utilisateurs des sysadm.

Exemple de code 2.1 : Récupérer un Makefile initial

# zcat /usr/share/doc/selinux-base-policy-20061008/Makefile.example.gz > /root/Makefile

5.c. Écrire un fichier TE

La plupart des déclarations sont utilisables dans un module, ainsi que quelques déclarations supplémentaires.

Exemple de code 3.1 : Exemple de local.te

policy_module(local,1.0)

require {
  type sysadm_su_t, newrole_t;
}
allow sysadm_su_t newrole_t:process sigchld;

En plus des règles de base, quelques déclarations sont requises par les modules de politiques. La première est une macro policy_module() qui contient le nom du module et sa version. Le bloc require suivant spécifie tous les types qui sont requis afin que le module puisse fonctionner. Tous les types utilisés dans un module doivent soit être déclarés dans ce module, soit requis par ce module.

5.d. Écrire un fichier FC (facultatif)

Le fichier de contextes est facultatif et utilise la même syntaxe que d'habitude.

Exemple de code 4.1 : Exemple de local.fc

/opt/myprogs/mybin  system_u:object_r:bin_t

Les types utilisés dans ce fichier de contexte doivent être requis ou déclarés dans le fichier TE.

5.e. Compiler les modules de politique

Lancez simplement make pour construire tous les modules du répertoire. Chaque module sera compilé pour fonctionner avec la politique courante, comme spécifié dans /etc/selinux/config.

Exemple de code 5.1 : Construction des modules

# make
Compiling strict local module
/usr/bin/checkmodule:  loading policy configuration from tmp/local.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 6) to tmp/local.mod
Creating strict local.pp policy package

Pour construire un module pour une politique différente que celle en place, utilisez l'option NAME=.

Exemple de code 5.2 : Construction des modules

# make NAME=targeted
Compiling targeted local module
/usr/bin/checkmodule:  loading policy configuration from tmp/local.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 6) to tmp/local.mod
Creating targeted local.pp policy package

5.f. Charger les modules

Les modules peuvent être chargés dans la politique courante simplement en utilisant la cible load du Makefile.

Exemple de code 6.1 : Charger les modules de politique

# make load

La cible load respecte également l'option NAME=. Accessoirement, la commande semodule peut être aussi utilisée pour charger des modules individuellement.

Exemple de code 6.2 : Charger un module individuel

# semodule -i local.pp

5.g. Faire un module avec la SELinux Reference Policy

La nouvelle politique de Gentoo est basée sur la SELinux Reference Policy. Pour plus d'information à propos de la construction d'un module selon SELinux Reference Policy, consultez le wiki Reference Policy.

6. Références sur SELinux

6.a. Généralités

6.b. La politique

6.c. Quelques livres

  • SELinux by Example: Using Security Enhanced Linux, Frank Mayer, Karl MacMillan, and David Caplan, Prentice Hall, 2006; ISBN 0131963694
  • SELinux: NSA's Open Source Security Enhanced Linux, Bill McCarty, O'Reilly Media, 2004; ISBN 0596007167

6.d. Notes de conférences

6.e. Présentations

2006 SELinux Symposium

2005 SELinux Symposium

D. Résolution des problèmes liés à SELinux

1. La politique n'est pas chargée au démarrage

1.a. Vérifier la disponibilité de la politique

Vous devez être dans sysadm_r pour effectuer cette action.

Une politique binaire doit être disponible dans /etc/selinux/{strict,targeted}/policy. Si ce n'est pas le cas, installez la politique.

Exemple de code 1.1 : Installer la politique

# semodule -n -B

1.b. Vérifier qu'init peut charger la politique

La dernière vérification consiste à s'assurer qu'init puisse charger la politique. Exécutez ldd sur /sbin/init et, si libselinux ne fait pas partie des bibliothèques listées, réinstallez sysvinit.

Exemple de code 2.1 : Vérifier la liaison d'init à libselinux

# ldd /sbin/init
  linux-gate.so.1 =>  (0xffffe000)
  libselinux.so.1 => /lib/libselinux.so.1 (0x40025000)
  libc.so.6 => /lib/libc.so.6 (0x40035000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Maintenant, redémarrez afin qu'init obtienne le bon contexte et puisse charger la politique.

2. Problème de connexion locale

2.a. Sommaire

Vous devez être dans sysadm_r pour effectuer ces actions.

Lancez sestatus -v et cliquez sur le premier contexte qui ne correspond pas :

Processus Contexte
Init context system_u:system_r:init_t
/sbin/agetty system_u:system_r:getty_t
Fichier Contexte
/bin/login system_u:object_r:login_exec_t
/sbin/unix_chkpwd system_u:object_r:chkpwd_exec_t
/etc/passwd system_u:object_r:etc_t
/etc/shadow system_u:object_r:shadow_t
/bin/bash system_u:object_r:shell_exec_t

2.b. Le contexte d'init est incorrect

Vérifier l'étiquette d'init

Plusieurs raisons peuvent être à l'origine d'un mauvais contexte pour init. Tout d'abord, vérifiez qu'init est correctement étiqueté en vous référant au résultat de sestatus concernant /sbin/init. Si ce n'est pas system_u:object_r:init_exec_t, ré-étiquetez sysvinit.

Exemple de code 2.1 : Réparer le contexte d'init

# rlpkg sysvinit

Vérifier la disponibilité de la politique

Vous devez être dans sysadm_r pour effectuer cette action.

Une politique binaire doit être disponible dans /etc/selinux/{strict,targeted}/policy. Si ce n'est pas le cas, installez la politique.

Exemple de code 2.2 : Installer la politique

# semodule -n -B

Vérifier qu'init peut charger la politique

La dernière vérification consiste à s'assurer qu'init puisse charger la politique. Exécutez ldd sur /sbin/init et, si libselinux ne fait pas partie des bibliothèques listées, réinstallez sysvinit.

Exemple de code 2.3 : Vérifier la liaison d'init à libselinux

# ldd /sbin/init
  linux-gate.so.1 =>  (0xffffe000)
  libselinux.so.1 => /lib/libselinux.so.1 (0x40025000)
  libc.so.6 => /lib/libc.so.6 (0x40035000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Maintenant, redémarrez afin qu'init obtienne le bon contexte et puisse charger la politique.

2.c. Le contexte d'Agetty est incorrect

Vérifier qu'Agetty est étiqueté correctement. Selon la sortie de sestatus concernant /sbin/agetty, si le contexte n'est pas system_u:object_r:getty_exec_t, ré-étiquetez util-linux. Ensuite, redémarrez tous les Agetty.

Exemple de code 3.1 : Réparer le contexte d'Agetty

# rlpkg util-linux
# killall agetty (Ils se relancent tous seuls.)

Tous les Agetty devraient maintenant se trouver dans le contexte system_u:object_r:getty_exec_t. Essayez de vous reconnecter à nouveau.

2.d. Le contexte de Login est incorrect

Le programme Login (/bin/login) n'est pas étiqueté correctement. Ré-étiquetez shadow.

Exemple de code 4.1 : Ré-étiquetez shadow

# rlpkg shadow

Le contexte de /bin/login devrait maintenant être system_u:object_r:login_exec_t. Essayez de vous reconnecter à nouveau.

2.e. Le contexte de PAM est incorrect

Sshd doit pouvoir utiliser PAM pour authentifier les utilisateurs. Le programme de PAM qui vérifie le mot de passe (/sbin/unix_chkpwd) doit être étiqueté correctement afin que Sshd puisse transiter vers le contexte de vérification du mot de passe. Ré-étiquetez PAM.

Exemple de code 5.1 : Réparer le contexte d'unix_chkpwd

# rlpkg pam

Le contexte du programme de vérification de mot de passe devrait maintenant être system_u:object_r:chkpwd_exec_t. Essayez de vous reconnecter à nouveau.

2.f. Les contextes des fichiers de mots de passes sont incorrects

Le fichier passwd (/etc/passwd) et shadow (/etc/shadow) doivent être correctement étiquetés sinon PAM ne pourra pas authentifier les utilisateurs. Ré-étiquetez les fichiers.

Exemple de code 6.1 : Réparer les contextes des fichiers de mots de passes

# restorecon /etc/passwd /etc/shadow

Leur contexte devraient maintenant être respectivement system_u:object_r:etc_t et system_u:object_r:shadow_t. Essayez de vous reconnecter à nouveau.

2.g. Le contexte de Bash est incorrect

Bash doit être correctement étiqueté afin que l'utilisateur puisse transiter vers son domaine lors de la connexion. Ré-étiquetez bash.

Exemple de code 7.1 : Réparer le contexte de bash

# rlpkg bash

Bash (/bin/bash) doit maintenant avoir le contexte system_u:object_r:shell_exec_t. Essayez de vous reconnecter à nouveau.

3. Problème de connexion distante

3.a. Sommaire

Vous devez être dans sysadm_r pour effectuer ces actions.

Lancez sestatus -v et cliquez sur le premier contexte qui ne correspond pas :

Processus Contexte
Init context system_u:system_r:init_t
/usr/sbin/sshd system_u:system_r:sshd_t
File Context
/sbin/unix_chkpwd system_u:object_r:chkpwd_exec_t
/etc/passwd system_u:object_r:etc_t
/etc/shadow system_u:object_r:shadow_t
/bin/bash system_u:object_r:shell_exec_t

3.b. Le contexte d'init est incorrect

Vérifier l'étiquette d'init

Plusieurs raisons peuvent être à l'origine d'un mauvais contexte pour init. Tout d'abord, vérifiez qu'init est correctement étiqueté en vous référant au résultat de sestatus concernant /sbin/init. Si ce n'est pas system_u:object_r:init_exec_t, ré-étiquetez sysvinit.

Exemple de code 2.1 : Réparer le contexte d'init

# rlpkg sysvinit

Vérifier la disponibilité de la politique

Vous devez être dans sysadm_r pour effectuer cette action.

Une politique binaire doit être disponible dans /etc/selinux/{strict,targeted}/policy. Si ce n'est pas le cas, installez la politique.

Exemple de code 2.2 : Installer la politique

# semodule -n -B

Vérifier qu'init peut charger la politique

La dernière vérification consiste à s'assurer qu'init puisse charger la politique. Exécutez ldd sur /sbin/init et, si libselinux ne fait pas partie des bibliothèques listées, réinstallez sysvinit.

Exemple de code 2.3 : Vérifier la liaison d'init à libselinux

# ldd /sbin/init
  linux-gate.so.1 =>  (0xffffe000)
  libselinux.so.1 => /lib/libselinux.so.1 (0x40025000)
  libc.so.6 => /lib/libc.so.6 (0x40035000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Maintenant, redémarrez afin qu'init obtienne le bon contexte et puisse charger la politique.

3.c. Le contexte de Sshd est incorrect

Une autre possibilité est que sshd ne soit pas étiqueté correctement et qu'il ne tourne donc pas dans le bon domaine. Ré-étiquetez openssh, puis relancez sshd.

Exemple de code 3.1 : Réparer le contexte de sshd

# rlpkg openssh
# /etc/init.d/sshd restart

3.d. Le contexte de PAM est incorrect

Sshd doit pouvoir utiliser PAM pour authentifier les utilisateurs. Le programme de PAM qui vérifie le mot de passe (/sbin/unix_chkpwd) doit être étiqueté correctement afin que Sshd puisse transiter vers le contexte de vérification du mot de passe. Ré-étiquetez PAM.

Exemple de code 4.1 : Réparer le contexte d'unix_chkpwd

# rlpkg pam

Le contexte du programme de vérification de mot de passe devrait maintenant être system_u:object_r:chkpwd_exec_t. Essayez de vous reconnecter à nouveau.

3.e. Les contextes des fichiers de mots de passes sont incorrects

Le fichier passwd (/etc/passwd) et shadow (/etc/shadow) doivent être correctement étiquetés sinon PAM ne pourra pas authentifier les utilisateurs. Ré-étiquetez les fichiers.

Exemple de code 5.1 : Réparer les contextes des fichiers de mots de passes

# restorecon /etc/passwd /etc/shadow

Leur contexte devraient maintenant être respectivement system_u:object_r:etc_t et system_u:object_r:shadow_t. Essayez de vous reconnecter à nouveau.

3.f. Le contexte de Bash est incorrect

Bash doit être correctement étiqueté afin que l'utilisateur puisse transiter vers son domaine lors de la connexion. Ré-étiquetez bash.

Exemple de code 6.1 : Réparer le contexte de bash

# rlpkg bash

Bash (/bin/bash) doit maintenant avoir le contexte system_u:object_r:shell_exec_t. Essayez de vous reconnecter à nouveau.

3.g. Autres problèmes avec sshd

Validité du shell

Premièrement, assurez-vous que le shell de l'utilisateur est valide.

Exemple de code 7.1 : Validité du shell

# grep utilisateur /etc/passwd | cut -d: -f7
/bin/bash (Doit renvoyer le shell de l'utilisateur.)

Si la commande précédente ne renvoie rien ou renvoie un shell incorrect, redéfinissez le shell de cet utilisateur.

Exemple de code 7.2 : Définir le shell de l'utilisateur

# usermod -s /bin/bash utilisateur

PAM activé

PAM doit être activé dans sshd. Vérifiez que cette ligne soit bien décommentée dans le fichier /etc/ssh/sshd_config :

Exemple de code 7.3 : Sshd doit utiliser PAM

UsePAM yes

SELinux ne permet actuellement qu'à PAM et à quelques rares autres programmes d'accéder directement au fichier /etc/shadow. Openssh doit donc utiliser PAM pour la vérification des mots de passes (cela ne concerne donc pas l'accès par clé publique).

Imprimer

Dernière mise à jour le 16 mai 2008

Résumé : Manuel SELinux pour Gentoo Linux.

Chris PeBenito
Author

Camille Huot
Traducteur

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.