J'ai repris un post de l'excellent Dan Walsh afin de bien
comprendre la subtilité des "capabilities" et sur les logs AVC DAC_READ_SEARCH et
DAC_OVERRIDE que je rencontre.
Commençons par un mythe bien connu : ROOT a tous les droits.
L'idée que ROOT possède tous les droits est une erreur. Cela
fait quelques années que le noyau Linux a essayé de décomposer les privilèges
de root en plusieurs fonctionnalités, les "capabilities".
A l'origine, ils étaient de 32 et sont passés récemment à
64.
Les capabilities donnent la possibilité au programmeur de
coder des applications de manière a ce que la commande ping par exemple puisse ouvrir une
socket ou httpd puisse ouvrir un port inférieur à 1024, sans utiliser les
autres capabilities de root.
SELinux contrôle également l'accès à toutes les
fonctionnalités d'un processus.
Un bugzilla courant concerne un processus nécessitant la
fonctionnalité DAC_READ_SEARCH ou DAC_OVERRIDE.
DAC (Discretionnary Access Control) signifie un contrôle
d'accès discrétionnaire. Cela indique que les droits sur un fichier sont
laissés à la discrétion du propriétaire
du fichier. En tant que propriétaire du fichier, vous pouvez modifier n'importe
quels droits dessus. Dans ce modèle, l'état est non déterminable par
l'administrateur. Et root outrepasse tout le contrôle d'accès. C'est le mode par défaut des systèmes Linux/ Unix avec les read-write-execute et users et groups.
Regardons maintenant la puissance des capabilities:
more /usr/include/linux/capability.h
...
/* Override all DAC access, including ACL execute access if
[_POSIX_ACL] is defined. Excluding DAC access covered by
CAP_LINUX_IMMUTABLE. */
#define CAP_DAC_OVERRIDE 1
/* Overrides all DAC restrictions regarding read and search on files
and directories, including ACL restrictions if [_POSIX_ACL] is
defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
#define CAP_DAC_READ_SEARCH 2
En lisant la description dans le code, cela signifie d’un
processus s'exécutant avec l'UID=0 peut lire tous les fichiers du système, même
si les flags de permissions n'autorisent pas root de lire le fichier.
De façon similaire, DAC_OVERRIDE signifie qu'un processus
peut ignorer les droits de permissions
et propriétaires de tous les fichiers d'un système.
Si on voit un message AVC qui requière cet accès, il faut
regarder l'UID du processus et bien souvent, ce processus s'exécute avec
l'uid=0.
Le réflexe dans la plupart du temps est d'ajouter des
autorisations, ce qui est bien souvent une erreur.
Ces AVC indique que vous avez des droits d'accès positionnés
pour restreindre l'accès à ces fichiers. Il s'agit souvent de fichiers de
configurations.
Prenons l'exemple du processus https ayant besoin de lire le
contenu de /var/lib/myweb/content avec comme propriétaire l'utilisateur httpd
et les permissions 600.
ls -l /var/lib/myweb/content
-rw-------. 1 apache apache 0 May 12 13:50 /var/lib/myweb/content
Si pour différente raison, le processus a besoin de lire ce
fichier et qu'il tourne avec l'UID=0, alors le système va refuser l'accès et
générer un DAC_* AVC.
Un simple fix serait de changer les permissions du fichier à
644.
# chmod 640 /var/lib/myweb/content
# chgrp root /var/lib/myweb/content
# ls -l /var/lib/myweb/content
-rw-r-----. 1 apache root 0 May 12 13:50 /var/lib/myweb/content
Cela va permettre à un processus root de lire le fichier en
utilisant les droits "other".
Une autre solution serait de changer le groupe du fichier à
root et de changer les permissions du fichier à 640.
A présent, root peut lire le fichier en fonction des
autorisations du groupe, mais other ne pourra pas le lire.
Il est possible aussi d'utiliser les ACL pour gérer les
access.
Au final, il ne s'agit pas d'un problème lié à SELinux, ni
d'un problème imposant d'assouplir la sécurité SELinux
Le problème avec SELinux est que le message AVC n'indique
pas quel objet du système de fichiers a bloqué l'accès par défaut. La raison
est celle de la performance.
Il faut donc activer l'audit complet et régénérer l'AVC afin
d'obtenir le chemin de l'objet avec les mauvais contrôles DAC.
# echo "-w /etc/shadow -p wr" >> /etc/audit/audit.rules
# service auditd restart
Ou de façon non permanente:
# auditctl -w /etc/shadow -p w
Aucun commentaire:
Enregistrer un commentaire