confs:selinux

Selinux

SELinux propose trois modes différents.

  • Dans le mode strict (Enforcing), les accès sont restreints en fonction des règles SELinux en vigueur sur la machine.
  • Le mode permissif (Permissive) peut être considéré comme un mode de débogage. Les règles SELinux sont interrogées, les erreurs d’accès sont enregistrées dans les logs, mais l’accès ne sera pas bloqué.
  • Lorsque SELinux est désactivé (Disabled), l’accès n’est pas restreint, et rien n’est enregistré dans les logs.

La commande getenforce vous informe sur le mode en vigueur sur votre machine.

$ getenforce
Enforcing

La commande setenforce permet de basculer temporairement – jusqu’au prochain redémarrage – entre les modes strict (Enforcing) et permissif (Permissive).

$ getenforce
Enforcing
$ sudo setenforce 0
$ getenforce
Permissive
$ sudo setenforce 1
$ getenforce
Enforcing

Le mode SELinux par défaut est défini dans le fichier /etc/selinux/config.

# /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted

Ici, SELINUX prendra une des trois valeurs enforcing, permissive ou disabled. Quant à SELINUXTYPE, on gardera la valeur par défaut targeted, qui garantit la surveillance des principaux services réseau. Lorsque SELinux est activé – autrement dit, lorsqu’on passe du mode disabled à permissive ou enforcing, il faut impérativement songer à réétiqueter l’ensemble des fichiers du système. Pour ce faire, il suffit de créer un fichier vide .autorelabel à la racine du système de fichiers avant de redémarrer.

$ sudo touch /.autorelabel
$ sudo reboot

Le réétiquetage du système de fichiers peut prendre un certain temps, en fonction de la taille de votre installation. Pour une première utilisation, je vous conseille d’opter pour le mode permissif par défaut. Cela évite de se retrouver avec un système qui ne démarre plus en mode strict.

Voir les contextes L’option -Z me permet d’afficher le contexte de sécurité de ces fichiers.

$ ls -Z
drwxr-xr-x. microlinux microlinux unconfined_u:object_r:httpd_sys_content_t:s0 css
drwxr-xr-x. microlinux microlinux unconfined_u:object_r:httpd_sys_content_t:s0 images
-rw-r--r--. microlinux microlinux unconfined_u:object_r:httpd_sys_content_t:s0 index.html

Cette même option -Z peut s’utiliser avec la commande ps pour afficher le contexte de sécurité d’un processus.

# ps axZ | grep httpd
system_u:system_r:httpd_t:s0   3948 ?   Ss  0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0   3949 ?   S   0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0   3950 ?   S   0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0   3951 ?   S   0:00 /usr/sbin/httpd -DFOREGROUND
... 

Un contexte SELinux est présenté sous la forme utilisateur:rôle:type:niveau. Laissons de côté les utilisateurs SELinux, les rôles et les niveaux, et concentrons-nous sur le type, qui correspond au troisième champ dans le contexte SELinux.

unconfined_u:object_r:httpd_sys_content_t:s0
system_u:system_r:httpd_t:s0

Nous avons vu que sur le serveur web en cours d’exécution, le processus httpd est étiqueté httpd_t. Les fichiers servis par Apache semblent tous munis de l’étiquette httpd_sys_content_t. Si nous affichons le contexte de sécurité des fichiers appartenant à Apache, nous constatons qu’ils semblent tous appartenir à une même famille en termes d’étiquettes.

Les fichiers de configuration sont étiquetés httpd_config_t.
Les fichiers logs sont tous de type httpd_log_t.

Les logs de SELinux ne sont pas ce qu’il y a de plus lisible, mais fort heureusement, il existe un outil pratique pour nous faciliter la tâche. Installez le paquet setroubleshoot-server et invoquez la commande suivante.

$ sudo sealert -a /var/log/audit/audit.log | less
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------
SELinux is preventing /usr/sbin/httpd from getattr access 
on the file /var/www/html/index.html.
***** Plugin restorecon (94.8 confidence) suggests *****
If you want to fix the label. 
/var/www/html/index.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped 
due to insufficient permissions to access a parent directory in which 
case try to change the following command accordingly. Do
# /sbin/restorecon -v /var/www/html/index.html
...

Notez au passage qu’ici, j’ai invoqué la commande sur un serveur configuré en anglais (LANG=en_US.utf8). Sur un système configuré en français, on obtient un mélange de français et d’anglais assez folklorique.

Quoi qu’il en soit, retenons le contenu de ce message d’erreur.

  • SELinux empêche Apache d’accéder au fichier index.html.
  • L’étiquette par défaut devrait être httpd_sys_content_t.
  • La commande restorecon permet de rétablir l’étiquette correcte.

Je vais suivre les recommandations sans toutefois les prendre au pied de la lettre, car je vais utiliser restorecon pour réétiqueter correctement tout le contenu de mon répertoire /var/www/html.

$ sudo restorecon -R -v /var/www/html/

Je recharge la page web, et je constate qu’elle s’affiche à nouveau correctement. Modifier le contexte SELinux

Les fichiers que nous avons créés dans /var/www/html étaient tous étiquetés httpd_sys_content_t, alors que leurs copies correspondantes dans /srv/html étaient de type var_t.

En mode strict aussi bien qu’en mode permissif, chaque fichier nouvellement créé à un certain endroit du système de fichiers sera étiqueté de manière appropriée par le système. La commande matchpathcon pourra nous renseigner sur l’étiquette utilisée en fonction du répertoire.

$ matchpathcon /var/www/html/
/var/www/html   system_u:object_r:httpd_sys_content_t:s0
$ matchpathcon /var/log/httpd/
/var/log/httpd  system_u:object_r:httpd_log_t:s0
$ matchpathcon /etc/httpd/conf/
/etc/httpd/conf system_u:object_r:httpd_config_t:s0

La commande restorecon que nous avons utilisée un peu plus haut s’est donc chargée de restaurer le contexte par défaut des fichiers rangés dans cette arborescence.

En revanche, si nous décidons de ranger des fichiers dans un endroit un peu moins orthodoxe du système, nous devrons nous charger de définir un contexte SELinux adapté pour l’arborescence en question. Le prochain exemple nous le montrera.

Admettons que je veuille ranger les fichiers de mon serveur web dans l’arborescence /srv/web/html plutôt que dans /var/www/html.

$ sudo mkdir -pv /srv/web/html
mkdir: created directory ‘/srv/web’
mkdir: created directory ‘/srv/web/html’

Comme on peut s’y attendre, le contexte SELinux par défaut de ce répertoire n’est pas adapté à son utilisation.

$ matchpathcon /srv/web/html/
/srv/web/html system_u:object_r:var_t:s0

Pour modifier le contexte par défaut de cette arborescence, je pourrais m’y prendre de la manière suivante.

$ sudo semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
$ sudo restorecon -R -v /srv/web/

L’opération se fait donc en deux temps et mérite d’ailleurs quelques remarques.

  • Comme on s’en doute, l’outil semanage avec l’option fcontext permet de gérer les contextes de sécurité SELinux.
  • L’option -a (–add) permet d’ajouter une entrée.
  • L’option -t (–type) spécifie le type, en l’occurrence httpd_sys_content_t.
  • L’utilisation de l’expression régulière '/srv/web(/.*)?' applique la directive récursivement sur toute l’arborescence.
  • Une fois que le contexte par défaut est défini, il faut l’appliquer avec restorecon.

Notons ici que la documentation de SELinux cite chcon comme premier outil pour modifier le contexte d’un fichier ou d’un répertoire. Le problème avec chcon, c’est qu’à la prochaine utilisation de restorecon sur le fichier ou ses parents, le fichier sera réétiqueté avec le contexte de son plus proche parent pour lequel un contexte spécifique est défini. Il vaut donc mieux prendre l’habitude d’utiliser semanage fcontext et restorecon pour éviter de se tirer dans le pied par la suite.

Dans ce quatrième exemple, nous mettons la pratique avant la théorie pour expliquer une autre particularité de SELinux.

Pour commencer, passez en mode permissif.

$ sudo setenforce 0

Nous allons activer l’affichage du contenu de ~/public_html pour les répertoires utilisateur. En partant de la configuration par défaut d’Apache, éditer /etc/httpd/conf.d/userdir.conf comme ceci.

<IfModule mod_userdir.c>
  # UserDir disabled
  UserDir public_html
</IfModule>

En tant que simple utilisateur, créez un répertoire ~/public_html, copiez la page web par défaut dans ce répertoire en l’éditant un tant soit peu et définissez les droits d’accès qui vont bien.

$ mkdir ~/public_html
$ cp -R /usr/share/httpd/noindex/* ~/public_html/
$ vim public_html/index.html (modifier le titre de la page)
$ chmod 0755 public_html
$ chmod 0711 ~

À partir de là, le site s’affiche à l’adresse http://amandine.microlinux.lan/~microlinux.

Repassons SELinux en mode strict.

$ sudo setenforce 1

Rafraîchissons la page, et nous nous retrouvons avec l’erreur suivante.

Les logs dans /var/log/httpd/error_log confirment qu’il s’agit d’un problème de droits d’accès, mais ne nous en disent pas plus. Jetons un oeil dans les logs de SELinux.

$ sudo sealert -a /var/log/audit/audit.log | less

La première alerte nous suggère de modifier le contexte du fichier /home/microlinux/public_html/index.html. Continuons un peu, et regardons de près la deuxième alerte.

*****  Plugin catchall_boolean (32.5 confidence) suggests   *****
If you want to allow httpd to enable homedirs
Then you must tell SELinux about this by enabling the 
'httpd_enable_homedirs' boolean. Do
setsebool -P httpd_enable_homedirs 1

Les booléens permettent de modifier une politique SELinux sans avoir à se plonger dans les arcanes de la rédaction de politiques. CentOS comporte quelques centaines de booléens, dont certains vont nous simplifier la vie.

Affichons les booléens qui concernent Apache.

$ getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
...

Nous pouvons en savoir un peu plus sur le rôle de chaque booléen.

$ sudo semanage boolean -l | grep httpd | sort
httpd_anon_write        (off, off) Allow httpd to anon write
httpd_builtin_scripting (on, on)   Allow httpd to builtin scripting
httpd_can_check_spam    (off, off) Allow httpd to can check spam
httpd_can_connect_ftp   (off, off) Allow httpd to can connect ftp
httpd_can_connect_ldap  (off, off) Allow httpd to can connect ldap

Reprenons le dernier exemple pratique et tentons de corriger la politique SELinux de manière à autoriser l’affichage du contenu de ~/public_html.

$ sudo setsebool -P httpd_enable_homedirs on

Notez qu’ici l’option -P rend la directive permanente, c’est-à-dire qu’elle est conservée après un redémarrage du système.

L’ensemble des booléens personnalisés apparaît dans le fichier /etc/selinux/targeted/active/booleans.local. Comme le suggère l’avertissement en tête de ce fichier, cela ne sert à rien de l’éditer directement, étant donné qu’il est automatiquement regénéré à chaque invocation de setsebool.

# This file is auto-generated by libsemanage
# Do not edit directly.
httpd_enable_homedirs=1
  • confs/selinux.txt
  • Last modified: 2024/10/14 20:59
  • by 127.0.0.1