Diagnostiquer un refus SELinux : des traces AVC aux contextes de fichiers

Diagnostiquer un refus SELinux : des traces AVC aux contextes de fichiers

Après le déplacement des fichiers web de leur répertoire d’origine vers /srv, httpd renvoie une erreur 403. Les fichiers sont pourtant lisibles et le service fonctionne : ce n’est pas une raison pour élargir les permissions ou désactiver SELinux. Les permissions classiques des fichiers, les règles d’autorisation du service et le contrôle d’accès obligatoire constituent trois niveaux de vérification distincts. Cet article s’appuie sur un hôte virtuel de test httpd déjà configuré sous AlmaLinux 9 pour relier la requête en échec aux événements AVC, corriger durablement les contextes de fichiers, puis vérifier le rétablissement du service et le respect des limites d’accès.

1. Définir le périmètre de test et consigner l’état initial

Les serveurs dédiés CloudDDR peuvent être configurés avec AlmaLinux 9. Après le paiement, consultez les identifiants dans la console et connectez-vous via SSH ; si plusieurs adresses sont disponibles, utilisez la première. Les opérations suivantes nécessitent des privilèges d’administration. Exécutez-les uniquement dans un environnement de test isolé, sans écraser de répertoire utilisé en production ni modifier les adresses d’écoute ou le pare-feu.

On suppose que httpd est déjà installé et que l’hôte virtuel de test ainsi que son point d’accès sont configurés. Commencez par sauvegarder la configuration de cet hôte virtuel et noter son DocumentRoot d’origine. Si des outils de diagnostic manquent, installez les paquets correspondants, puis vérifiez le mode SELinux et le service d’audit :

sudo dnf install policycoreutils-python-utils
getenforce
sestatus
sudo systemctl status auditd --no-pager
sudo semanage fcontext -l -C
sudo semanage permissive -l

Le mode global attendu est Enforcing, et le domaine dans lequel s’exécute httpd ne doit pas avoir été placé individuellement en mode permissif. Si le service d’audit ne fonctionne pas correctement, rétablissez d’abord la collecte des événements : l’absence de refus dans les journaux ne prouve pas que l’accès n’a pas été restreint. Conservez la liste des correspondances locales de contextes afin de pouvoir distinguer ensuite les règles existantes de celles ajoutées pendant ce test.

setenforce 0 ne constitue pas une correction. Si la requête réussit après la désactivation du contrôle obligatoire, cela fournit seulement une piste de diagnostic ; cela ne prouve pas que le service fonctionnera une fois le mode enforcing rétabli.

2. Écarter d’abord les erreurs de permissions classiques et de configuration

Créez un répertoire réservé au test, contenant uniquement une ligne servant de marqueur de validation. Les répertoires doivent pouvoir être traversés et le fichier doit être lisible. Ces permissions conviennent uniquement à du contenu de test public, pas à des clés, des sauvegardes ou des données de production.

sudo install -d -m 0755 /srv/selinux-lab
printf 'selinux-lab-ok\n' | sudo tee /srv/selinux-lab/index.html
sudo chmod 0644 /srv/selinux-lab/index.html
namei -l /srv/selinux-lab/index.html
ls -ldZ /srv/selinux-lab
ls -lZ /srv/selinux-lab/index.html

Dans l’hôte virtuel de test existant, définissez la racine documentaire et les autorisations du répertoire correspondant comme suit :

DocumentRoot "/srv/selinux-lab"

<Directory "/srv/selinux-lab">
    AllowOverride None
    Options -Indexes
    Require all granted
</Directory>

Avant la modification, vérifiez comment les fichiers de configuration s’incluent les uns dans les autres, afin d’éviter qu’une autre section de répertoire ne remplace les autorisations prévues. Vérifiez la syntaxe avec httpd -t et utilisez httpd -S pour confirmer l’hôte virtuel auquel la requête sera adressée. Ne rechargez la configuration qu’une fois ces vérifications réussies.

Définissez la variable shell CHECK_URL avec l’URL réelle du test, en utilisant le chemin /index.html. Cette URL doit correspondre à l’hôte virtuel concerné ; n’y insérez aucun identifiant. Lors de la requête, vérifiez le corps de la réponse, pas seulement la réussite de la connexion :

sudo httpd -t
sudo httpd -S
sudo systemctl reload httpd
curl --fail --show-error "$CHECK_URL"

En cas d’échec, consultez d’abord le journal d’erreurs de httpd. L’absence de permission d’exécution sur un répertoire parent, la sélection du mauvais hôte virtuel ou un refus par les règles d’autorisation peuvent produire des symptômes similaires. À ce stade, élargir récursivement les permissions ne résout pas un problème de contexte SELinux et augmente la surface d’exposition.

3. Identifier le sujet, l’objet et l’action dans les événements AVC

Notez l’heure de la requête et ne reproduisez qu’une seule fois l’opération en échec, puis recherchez les refus sur la même période :

sudo ausearch -m AVC,USER_AVC -ts recent -i
ps -eZ | grep '[h]ttpd'
matchpathcon -V /srv/selinux-lab/index.html

Dans les événements AVC, examinez en priorité scontext, tcontext, tclass et les permissions refusées. scontext indique le domaine du processus à l’origine de l’accès, tandis que tcontext décrit le contexte de sécurité de l’objet cible. Lire un fichier et rechercher une entrée dans un répertoire sont deux actions distinctes : le seul nom du processus ne suffit pas à établir le diagnostic.

Reliez le chemin, le processus et l’horodatage de l’événement à la requête en échec. Lorsqu’une recherche dans un répertoire est refusée, vérifiez également chaque répertoire composant le chemin ; corriger uniquement le fichier final peut rester sans effet. Si le journal ne contient pas le chemin, utilisez le numéro de l’événement d’audit pour consulter les autres enregistrements associés au même événement.

L’absence d’AVC ne permet pas d’exclure avec certitude un problème SELinux. Vérifiez d’abord la période recherchée, l’état de l’audit et le domaine réel des processus du service. Si vous ne trouvez toujours aucun élément lié à la requête, reprenez le diagnostic de la configuration applicative et des permissions classiques, sans ajouter de règles d’autorisation à l’aveugle. N’envoyez pas non plus tous les refus historiques à un outil de génération de politique : ils peuvent concerner d’autres services.

4. Corriger durablement les contextes du contenu web

Pour du contenu statique ordinaire destiné à être lu par httpd, httpd_sys_content_t est le type prévu par la politique existante. N’ajoutez une correspondance ciblée que si les éléments recueillis montrent que les contextes du chemin de test ne conviennent pas à cet usage :

sudo semanage fcontext -a -t httpd_sys_content_t \
    '/srv/selinux-lab(/.*)?'
sudo restorecon -Rv /srv/selinux-lab
matchpathcon -V /srv/selinux-lab/index.html
ls -lZ /srv/selinux-lab/index.html

Si une expression strictement identique existe déjà, examinez la règle existante et modifiez-la avec -m si nécessaire, au lieu de multiplier les règles. L’expression doit couvrir uniquement le répertoire de test, sans attribuer le type de contenu web à l’ensemble de /srv. semanage enregistre la correspondance entre le chemin et le type ; c’est restorecon qui applique ensuite le contexte attendu aux fichiers existants.

chcon modifie directement le contexte actuel sans créer de correspondance persistante. Il ne peut donc pas remplacer cette étape : un réétiquetage ultérieur risque d’annuler la modification temporaire.

Le service n’a pas besoin d’écrire dans un répertoire de contenu statique. Pour supprimer un refus ponctuel, ne remplacez pas tous les contextes par un type autorisant l’écriture et n’activez pas de booléens sans rapport avec le problème. Si des besoins d’écriture existent réellement, par exemple pour des téléversements ou un cache, prévoyez un répertoire distinct et définissez ses permissions et ses contextes en fonction des actions nécessaires.

5. Valider le rétablissement et conserver une possibilité de retour arrière

Restez en mode enforcing, accédez de nouveau à la même URL et confirmez que le corps de la réponse contient selinux-lab-ok. Vérifiez également l’absence de nouveaux événements AVC associés à cette requête. Exécutez ensuite à nouveau restorecon, redémarrez le service de test et répétez la requête pour vous assurer que la correction ne dépend ni d’un contexte temporaire ni de l’état d’un ancien processus.

getenforce
sudo restorecon -Rv /srv/selinux-lab
sudo systemctl restart httpd
curl --fail --show-error "$CHECK_URL"
sudo ausearch -m AVC,USER_AVC -ts recent -i

La validation doit aussi inclure des tests négatifs : une requête visant un fichier inexistant doit échouer ; le répertoire de test ne doit pas autoriser l’affichage de son contenu ; le service ne doit pas présenter de nouveau point d’écoute inattendu ; les modifications locales de contextes doivent se limiter au chemin convenu. Ces contrôles vérifient respectivement le comportement de l’application, la configuration et le périmètre des changements : ils ne se substituent pas les uns aux autres.

À la fin du test, restaurez d’abord la configuration d’origine de l’hôte virtuel, vérifiez sa syntaxe et rechargez-la, puis supprimez le répertoire de test. Vous pouvez supprimer la correspondance effectivement ajoutée pendant cette procédure. Si une correspondance existante a été modifiée, rétablissez le type consigné au départ. Après le nettoyage, exécutez restorecon sur les chemins conservés.

Conservez enfin la requête en échec, les événements AVC associés, les contextes avant et après modification, l’expression de correspondance et le résultat de la réponse après redémarrage. Une requête réussie atteste seulement du rétablissement fonctionnel. Une validation complète exige aussi que le mode de sécurité soit resté inchangé, que les contextes puissent être réappliqués à partir de la correspondance persistante et que le périmètre des accès n’ait pas été élargi.

Questions fréquentes

Une réponse HTTP 403 prouve-t-elle un blocage SELinux ?

Non. Il faut vérifier les droits de traversée des répertoires, la lecture des fichiers et les règles d’accès httpd, puis rapprocher la requête refusée d’une trace AVC de la même période.

Pourquoi ne pas utiliser directement chcon ou générer une règle d’autorisation ?

restorecon peut annuler les contextes définis par chcon. Pour des fichiers web ordinaires, utiliser semanage fcontext puis restorecon. Avant de générer une règle, éliminer les erreurs de contexte, de chemin et de paramètres de politique existants.

Serveur dédié AMD EPYC 7543P à partir de $447/mois.

Configuration du serveur dédié : choisir la capacité mémoire

AMD EPYC 7543P, avec 128 Go ou 256 Go de DDR4-3200 ECC.