Vous êtes sur la page 1sur 9

SElinux : Security-Enhanced Linux

I. SELinux, c'est quoi ?

SElinux - pour « Security-Enhanced Linux » - permet de définir des politiques d'accès à


différents éléments du système d'exploitation. Ces éléments peuvent être des processus (démons),
ou encore des fichiers.

Remarque : Sous Linux, tout est fichier (Les disques, les processus, les interfaces réseau, les
informations concernant la mémoire ou le CPU, etc...)

Chaque processus est confiné à un (plusieurs) domaine, et les fichiers sont étiquetés en
conséquence. Pour simplifier, un processus ne peut accéder qu'aux fichiers étiquetés pour le
domaine auquel il est confiné.
L'on peut considérer que SELinux apporte une couche supplémentaire aux traditionnels droits
d'accès aux fichiers Unix. Bien que cette définition soit sûrement quelque peu simpliste, elle permet
de comprendre un peu mieux les problèmes que vous pouvez rencontrer avec SELinux.

SELinux vient améliorer la sécurité des serveurs sur lesquels il est déployé. Si un processus est
corrompu sur un serveur, il n'aura tout de même accès qu'aux fichiers étiquetés pour y-celui ; et ne
pourra rien faire d'autre que ce pour quoi il a été défini au départ.
SELinux n'a pas vocation à remplacer quelque système de sécurité existant, mais plutôt de les
compléter. Aussi, la mise en place de politiques de sécurité (programmes à jour, firewalls, mots de
passe complexes et modifiées régulièrement, ...) reste bien évidement de mise.

II. Les modes

SELinux propose trois modes différents :


✓ Appliqué (Enforcing) : il s'agit du mode proposé par défaut à l'installation de Centos. Dans ce
mode, les accès sont restreints en fonction des règles SELinux en vigueur sur la machine ;
✓ Permissif (Permissive) : ce mode est généralement à considérer comme un mode de débogage.
En mode permissif, les règles SELinux seront interrogées, les erreurs d'accès loguées, mais l'accès
ne sera pas bloqué. Ce mode peut être utile pour constater l'ensemble des erreurs SELinux
posées par un processus particulier par exemple ;
✓ Désactivé (Disabled) : SELinux est désactivé. Rien ne sera restreint, rien ne sera logué.

Pour modifier ou afficher le mode de SElinux on a :


La commande getenforce vous informera sur le mode actuellement actif sur votre machine.
La commande setenforce permet de basculer de façon temporaire (la modification ne sera
pas prise ne compte au prochain redémarrage de votre machine) entre les
modes Appliqué et Permissif :
Mode permissif : # setenforce 0
Mode appliqué : # setenforce 1
Le changement de mode peut également être appliqué de façon permanente via l'interface
graphique #system-config-selinux

Il est tout-à-fait possible de modifier manuellement le fichier /etc/selinux/config en


modifiant la ligne SELINUX= (enforcing | permissive | disabled). Soyez prudent car si vous faites une
faute, le système ne démarrera pas. Quant à SELINUXTYPE, on gardera la valeur par défaut targeted,
qui garantit la surveillance des principaux services réseau.
Attention !
Lorsque SELinux est exécuté en mode permissif ou s'il est désactivé, les nouveaux fichiers
crées ne porteront aucune étiquette. Lorsque SELinux sera réactivé, cela pourra poser des
problèmes, et il vous faudra donc réétiqueter l'intégralité de votre système. Pour ce faire, entrez la
commande suivante :
# touch /.autorelabel
# reboot
Puis redémarrez votre système. Au démarrage, l'intégralité de vos fichiers sera réétiquetée, cela peut
prendre un certain temps ; à plus forte raison si vous avez beaucoup de fichiers. Une autre méthode
consiste à saisir les commandes suivantes :
# fixfiles -F onboot
# reboot

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: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 23
Policy from config file: targeted

Aussi d’une façon générale, vous pouvez consulter les informations de l'actuel contexte
SELinux avec l'argument -Z (cet argument est utilisé par ps, ls, ...).

Avec CMD ps :
Exemple 1 : liste des contextes pour tous les processus :
# ps -ef -Z
LABEL UID PID PPID C STIME TTY TIME CMD
system_u:system_r:init_t:s0 root 1 0 0 May09 ? 00:00:02 /sbin/init
system_u:system_r:kernel_t:s0 root 2 0 0 May09 ? 00:00:00 [kthreadd]
system_u:system_r:kernel_t:s0 root 3 2 0 May09 ? 00:00:00 [migration/0]
system_u:system_r:kernel_t:s0 root 4 2 0 May09 ? 00:00:12 [ksoftirqd/0]

Exemple 2 : liste des contextes pour le processus httpd :


# ps -ef -Z | grep httpd
system_u:system_r:httpd_t:s0 root 2792 1 0 May09 ? 00:00:18 /usr/sbin/httpd
system_u:system_r:httpd_t:s0 apache 13928 2792 0 May13 ? 00:00:01 /usr/sbin/httpd
system_u:system_r:httpd_t:s0 apache 18787 2792 0 May10 ? 00:00:07 /usr/sbin/httpd
system_u:system_r:httpd_t:s0 apache 18899 2792 0 May10 ? 00:00:08 /usr/sbin/httpd
system_u:system_r:httpd_t:s0 apache 18901 2792 0 May10 ? 00:00:08 /usr/sbin/httpd
system_u:system_r:httpd_t:s0 apache 18902 2792 0 May10 ? 00:00:09 /usr/sbin/httpd

Avec CMD ls : contexte des fichiers du dossier /var/www/ :


# ls -alZ /var/www/
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x root root system_u:object_r:var_t:s0 ..
drwxr-xr-x root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 error
Les contextes des différents fichiers sur votre système sont définis par les règles SELinux
installées sur votre système. Additionnellement, certains paquets peuvent fournir leur propres
modules SELinux (pour la simple et bonne raison que la politique en question n'est pas intégrée à la
liste générale). Dans ce cas, on peut rencontrer deux cas de figure :
✓ Les paquets qui intègrent directement le module SELinux (BackupPC, PHP, ...) ;
✓ Les paquets qui fournissent le module SELinux sous forme de sous paquet (memcached, pure-
ftpd, ...).

III. Comprendre un contexte SELinux

Un contexte SELinux est présenté de la manière suivante :


Utilisateur : rôle : type : niveau
Pour le contexte du dossier /var/www/html :
system_u : object_r : httpd_sys_content_t : s0 html
Nous avons donc :
✓ L’utilisateur est system_u
✓ Le rôle object_r
✓ Le type httpd_sys_content_t
✓ Et le niveau s0

Utilisateurs
Tout utilisateur Linux est mappé à un utilisateur SELinux par la politique actuelle. Ce mappage
permet l'héritage des droits et restrictions de l'utilisateur SELinux correspondant.
La liste des utilisateurs SELinux peut être obtenue avec la commande :
# semanage login -l
Nom (session) Identité SELinux Intervalle MLS service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *

Rôles
Les rôles sont l'intermédiaire entre les utilisateurs et les domaines SELinux. Les domaines sont
accessibles par des rôles définis, et les rôles sont eux-mêmes accessibles par des utilisateurs définis.

Types
Un type SELinux est en quelque sorte un regroupement d'objets sur leur similarité d'un point
de vue sécurité ; qui ne sont donc pas liés à un contexte ou à un fichier particulier. Par exemple, les
dossiers personnels des utilisateurs peuvent contenir des contenus très différents, donc la
particularité commune est d'appartenir à un utilisateur ; on trouvera dans ce cas précis le
type home_user_t.

Niveau
La notion de niveaux dans SELinux (MLS) est bien trop vaste et pointue pour être abordée ici.
Vous trouverez de la documentation à ce sujet à différents endroits :

• http://selinuxproject.org/page/NB_MLS ;
• http://fedoraproject.org/wiki/SELinux/FedoraMLSHowto ;
• http://fedoraproject.org/wiki/SELinux/MLS .

Chaque processus est confiné à son propre domaine, et ne pourra pas accéder à des
informations qui ne sont pas placées dans le bon contexte. Il est possible de connaître la liste des
contextes auxquels peut accéder un processus à l'aide de la commande sesearch. Pour exécuter
cette commande, le paquet setools-console doit-être installé.
# yum install setools-console
Pour le processus httpd par exemple :
# sesearch --allow -s httpd_t -c file -p write
Option :
-A : Search for allow rules.
-s contexte : Find rules with type/attribute NAME as their source.
-c classe : Find rules with class NAME as their object class.
-p perm : Find rules with at least one of the specified permissions
Résultat :
allow httpd_t httpd_t : file { ioctl read write getattr lock append } ;
allow @ttr2119 xdm_home_t : file { ioctl read write getattr lock append } ;
allow httpd_t @ttr2306 : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t squirrelmail_spool_t : file { ioctl read write create getattr setattr lock append unlink link
rename open } ;
allow httpd_t httpd_cache_t : file { ioctl read write create getattr setattr lock append unlink link rename
open } ;
allow httpd_t httpd_tmpfs_t : file { ioctl read write create getattr setattr lock append unlink link rename
open } ;
allow httpd_t httpd_tmp_t : file { ioctl read write create getattr setattr lock append unlink link rename open
};
allow httpd_t httpd_squirrelmail_t : file { ioctl read write create getattr setattr lock append unlink link
rename open } ;
allow @ttr2119 user_tmp_t : file { ioctl write getattr lock append } ;

Tout fichier qui ne serait pas étiqueté avec l'un des contextes listés ne serait pas accessible
par le processus httpd ; donc votre serveur apache n'aurait pas le droit de lire le fichier, et ce même
si les droits linux le lui permettent.

TP 1 :

Dans la pratique, nous prendrons l'exemple d'un simple fichier html, que l'on souhaite servir
avec apache.
Pour les besoins de l'exercice :
1. Installer httpd :
#yum install httpd
2. Créer un dossier de travail dans /var/www/html/tux
# mkdir /var/www/html/selinux
3. Changer le propriétaire de dossier par votre nom
#chown -R tux1:tux1 /var/www/html/tux
4. Créez le fichier HTML nommé index.html, et insérez-y le code suivant :
#nano /var/www/html/tux/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title>Test de SELinux</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>SELinux me permet d'afficher cette page, il est fort aimable </p>
</body>
</html>
Puis :
#chown tux1.tux1 /var/www/html/tux/index.html
Voyons maintenant ce que tout cela donne, du point de vue du contexte SELinux :
$ ls -alZ /var/www/html/tux/
Résultat :
drwxr-xr-x. tux1 tux1 unconfined_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

5. Avec un navigateur web (firefox, arora, lynx, ou autre !), ouvrez maintenant
l'URL : http://localhost/tux/index.html. Vous vous rendrez compte que ça fonctionne.
Explication :
En inspectant la sortie de ls sur le dossier /var/www/html/tux, vous pourrez constater que le dossier
sont étiquetés httpd_sys_content_t ; et que c'est un des contextes auquel le processus httpd peut
accéder ; SELinux a donc permis à apache d'accéder à ce fichier.

Tentons une seconde manipulation :


1. Copier le fichier
#cp /var/www/html/tux/index.html /tmp/selinux.html
#mv /tmp/selinux.html /var/www/html/tux/
#chown tux1.tux1 /var/www/html/tux/selinux.html
2. Voyons ce que racontent les contextes SELinux :
# ls -lZ /var/www/html/tux/
-rw-rw-r-- tux1 tux1 unconfined_u:object_r:httpd_sys_content_t:s0 index.html
-rw-rw-r-- tux1 tux1 unconfined_u:object_r:user_tmp_t:s0 selinux.html
3. Maintenant, ouvrez l'URL http://localhost/tux/selinux.html.
Votre navigateur vous dira « Forbidden - You don't have permission to access…..».
Var_t et default_t
Pourquoi ? La raison est simple : le fichier /var/www/html/selinux/selinux.html est
étiqueté user_tmp_t ; contexte auquel le processus apache n'est pas autorisé à accéder, SElinux vous
empêchera d'accéder à ce fichier.

Solution

Vous aurez deux possibilités généralement pour corriger un contexte de fichier erroné :
➢ Spécifier un contexte « manuellement » : exige que vous sachiez ce que vous êtes en train de
faire. Il ne s'agit pas ici d'attribuer un contexte SELinux au hasard, ni de donner trop de droits à
apache sur ce fichier.
➢ Restaurer le contexte par défaut du chemin.

1. Restauration du contexte "par défaut"

La commande matchpathcon vous indique quel contexte devrait posséder votre fichier :
# matchpathcon /var/www/html/tux/selinux.html
/var/www/html/selinux/selinux.html system_u:object_r:httpd_sys_content_t:s0

Dans notre cas, restaurer le contexte qui aurait de l’être appliqué (httpd_sys_content_t) fera
l'affaire, essayons donc cela :
# restorecon -v /var/www/html/tux/selinux.html
restorecon permet de restaurer le(s) contexte(s) original(aux) du ou des chemins spécifiés. On voit ici
que le contexte de notre fichier erroné est passé de user_tmp_t à httpd_sys_content_t. Notre fichier
est désormais accessible par apache, et l'URL http://localhost/tux/selinux.html fonctionne.

2. Modification du contexte selon vos besoins

Parfois, il peut être nécessaire de spécifier par vous-mêmes le contexte désiré. Cela peut être
due au fait qu'un fichier se trouve dans un dossier qui n'est à la base pas prévu pour cette utilisation,
il peut s'agir d'un paquet qui ne prend pas en compte SELinux, ou d'un programme que vous installez
à la main, ...

Par exemple, dans le dossier /usr/share. le contexte par défaut de ce dossier n'autorise pas
apache à le lire :
# matchpathcon /usr/share/
/usr/share system_u:object_r:usr_t:s0

Tout dossier ou fichier créé dans /usr/share obtiendra alors un contexte usr_t, auquel
apache n'a pas accès (se reporter à la liste des contextes auxquels apache peut avoir accès, plus haut
dans ce tutoriel).
En gros, pour apache, si vous souhaitez placer des fichiers ou dossiers qui doivent être accessibles en
dehors de /var/www, vous aurez à en modifier le contexte SELinux.

Deux solutions sont possibles :


➢ chcon
➢ semanage
chcon permet de changer le contexte SELinux d'un fichier ou dossier donné, mais pas de façon
permanente. Je m'explique : pour le cas qui nous a préoccupés plus tôt, nous avions un fichier
étiquetté user_tmp_t au lieu de httpd_sys_content_t. Nous aurions pu, au lieu d'utiliser restorecon,
entrer plutôt :
# chcon -t httpd_sys_content_t /var/www/html/tux/selinux.html
Cette façon de faire n'aurait posé aucun problème.
En revanche, si nous utilisons chcon pour placer un autre contexte sur le fichier, par
exemple unconfined_t :
# chcon -t unconfined_t /var/www/selinux/selinux.html
Ça fonctionnera comme escompté, bien entendu, mais au prochain ré-étiquetage du disque ou à la
prochaine utilisation de restorecon sur le fichier ou sur ses parents, le fichier sera réétiquette avec le
contexte de son plus proche parent pour lequel un contexte spécifique est défini, en
l'occurrence /var/www.

semanage, en revanche, ne vous permet pas de modifier directement le contexte d'un fichier ou d'un
dossier, mais de définir un contexte par défaut qui sera appliqué par restorecon ou lors d'un ré-
étiquetage du système de fichiers. Cette solution est donc à privilégier lorsque l'on souhaite placer
un contexte qui restera.
# semanage fcontext -a -t httpd_sys_content_t '/var/www/html(/.*)?'
Puis appliquer le contexte par défauts :
# restorecon -R -v /var/www/html/tux/*

Remarque :
Les chemins déclarés via semanage sont stockés dans le fichier :
/etc/selinux/targeted/contexts/files/file_contexts.local
Pour supprimer le contexte personnalisé pour /var/www/html/tux :
# semanage fcontext -d '/var/www/html (/.*)?'
IV. Les booléens

Les booléens permettent de modifier une politique SELinux, sans avoir la moindre
connaissance ou compétence sur le sujet de la rédaction de politiques. L'activation ou la désactivation
d'un booléen ne requiert pas la compilation ou le rechargement d'un module.
CentOS comporte un certain nombre de booléens SELinux qui vont vous simplifier la vie...
Pour les lister, et obtenir quelques informations sur l'utilité de chacun, utilisez :
# semanage boolean -l
Pour simplement lister les booléens, sans aucune information complémentaire :
$ getsebool -a

Remarque
La commande semanage est bien plus générique que getsebool et setsebool , puisqu'elle permet
d'intervenir sur beaucoup d'autres aspects que les booléens, alors que les secondes sont très
spécifiques. De plus, semanage boolean ne peut être lancé qu'en tant que root.
getsebool et setsebool peuvent être lancées en tant qu'utilisateur simple.

Exemple :
# semanage boolean -l | grep httpd
httpd_can_network_relay (fermé,fermé) Autoriser à httpd d’agir en tant que relais
httpd_can_connect_mythtv (fermé,fermé) Autorise le démon http à se connecter à mythtv
httpd_can_network_connect_db (fermé,fermé) Autoriser les scripts et modules HTTPD à se
connecter aux bases de données sur le réseau.
httpd_use_gpg (fermé,fermé) Autoriser httpd à exécuter gpg
httpd_dbus_sssd (fermé,fermé) Autoriser Apache à communiquer avec le service sssd via
dbus
httpd_enable_cgi (ouvert,ouvert) Autoriser la prise en charge de cgi pour httpd
httpd_verify_dns (fermé,fermé) Autoriser Apache à interroger les enregistrements NS
httpd_dontaudit_search_dirs (fermé,fermé) Dontaudit Apache pour rechercher les répertoires.

Prenons un cas. Je veux utiliser la possibilité d'envoyer des emails à l'aide de la


fonction mail() de PHP, et SELinux bloque systématiquement l'envoi de mails par apache. Pour ce cas,
il suffit d'activer le booléen en question :
# setsebool -P httpd_can_sendmail on
L'option -P permet de rendre la directive permanente, et donc de la conserver en cas de réamorçage
du système.

V. Interface graphique

Une interface graphique est disponible pour la gestion des différents paramètres de SELinux.
Normalement, l'interface est installée par défaut, si tel n'était pas le cas, faites simplement :
# yum install policycoreutils-gui

Lorsque vous lancez l'outil, vous vous retrouver face à un écran qui ressemble à ce qui suit :
# system-config-selinux
La partie gauche, vous permet d'accéder aux différents aspects : les booléens, les règles des dossiers
et fichiers
La partie droite, sur la capture d'écran ci-dessus, vous permet de modifier le mode courant de
SELinux.
La case « Ré-étiquetage » forcera le ré-étiquetage de l'intégralité de votre système.
La fenêtre qui suit vous aide à gérer les booléens SELinux :

Le dernier exemple que je prendrai ici concerne les règles appliquées de façon permanente aux
dossiers et aux fichiers :

Résumé des commandes


Voici un bref résumé des commandes qui peuvent être utiles lorsque l'on se frotte à SELinux...
Consultation :
✓ sestatus : afficher le status actuel de SELinux ;
✓ getenforce : obtenir le mode SELinux courant de votre machine ;
✓ ls -Z : afficher la liste des fichiers et dossiers ainsi que leur contexte SELinux avec la
commande ls (pour plus d'options, consultez le man ls) ;
✓ ps -Z : afficher la liste des processus ainsi que leur contexte SELinux avec la
commande ps (pour plus d'options, consultez le man pas) ;
✓ sesearch : effectuer une recherche dans la politique actuellement configurée pour votre
machine ;
✓ getsebool : obtenir des informations sur les booléens ;
✓ matchpathcon : afficher le contexte que devrait posséder un fichier.
Modification :
✓ setenforce : modifier le mode SELinux de votre machine ;
✓ setsebool : modifier la valeur d'un booléen ;
✓ restorecon : restaurer un contexte en fonction de la politique courante ;
✓ chcon : modifier le contexte SELinux d'un fichier ;
✓ semanage : gérer les politiques SELinux.

Vous aimerez peut-être aussi