Les droits sous Linux répondent à la question « qui peut lire ce fichier ». AppArmor en pose une autre : « qu’est-ce que ce programme a le droit de faire ». La différence apparaît lors d’une intrusion. Un web shell s’exécute sous l’utilisateur du serveur web et hérite de tous ses droits — soit la lecture de la moitié du système. Un profil AppArmor restreint le processus à la liste de ce dont il a besoin pour travailler, et une tentative de lire /etc/shadow ou de lancer /bin/bash se solde par un refus, indépendamment des droits de l’utilisateur.
Ce qui est déjà actif
sudo aa-status
La sortie répond à trois questions : combien de profils sont chargés, combien d’entre eux sont en mode enforce et complain, et quels processus tournent sans aucun profil. Sur un Ubuntu typique, il y aura quelques dizaines de profils, mais presque tous pour des utilitaires comme man et tcpdump. Les services essentiels — nginx, Apache, PHP-FPM — sont d’ordinaire absents de la liste des processus confinés.
Trois modes à distinguer :
- enforce — les règles s’appliquent, tout le superflu est interdit ;
- complain — les infractions sont seulement consignées, rien n’est bloqué. C’est le mode de mise au point ;
- unconfined — il n’y a pas de profil, le programme tourne sans restriction.
La partie la plus utile de la sortie d’aa-status est la dernière : les processus qui écoutent le réseau et ne sont confinés par rien. C’est la liste par laquelle commencer.
Les outils
sudo apt install apparmor-utils
Sans ce paquet, les commandes aa-complain, aa-enforce et aa-logprof n’existent pas dans le système, bien qu’AppArmor lui-même fonctionne.
Comment activer un profil sans arrêter le service
L’ordre est fondamental. Un profil passé d’emblée en enforce interdira très probablement au service quelque chose de nécessaire, et il cessera de fonctionner — d’ordinaire pas tout de suite, mais lors d’une opération rare comme un téléversement de fichier ou l’envoi d’un courriel.
La bonne séquence :
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Une semaine de fonctionnement dans ce mode, en couvrant tous les scénarios exceptionnels : une sauvegarde, une mise à jour, le téléversement de gros fichiers. Puis l’examen de ce qui s’est accumulé :
sudo aa-logprof
La commande parcourt les infractions enregistrées et demande pour chacune s’il faut l’autoriser. L’attention est ici requise : autorisez ce qui relève réellement du travail du service, et non tout à la suite — sinon vous obtiendrez un profil qui autorise tout, et le sens en est perdu.
Et seulement ensuite :
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Où voir les refus
Toutes les infractions arrivent dans le journal du noyau :
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
Le second fichier existe si auditd est installé — et les entrées y sont sensiblement plus détaillées. Un enregistrement de refus montre le nom du profil, l’opération demandée et le chemin visé ; cela suffit à savoir s’il faut corriger le profil ou se réjouir du déclenchement.
Un symptôme mérite d’être retenu : un service se comporte étrangement — il ne lit pas une configuration, n’écrit pas dans un répertoire, n’ouvre pas une socket — tandis que ses propres journaux affichent une erreur « permission refusée » avec des droits manifestement corrects. C’est presque toujours AppArmor, et la première chose à faire est de regarder le journal du noyau.
Une mesure pratique, pas théorique
Un profil pour PHP-FPM ou nginx se rentabilise de façon concrète. Le processus étant confiné, un web shell parvenu sur le site ne peut ni lire les fichiers système, ni lancer un interpréteur, ni écrire hors des répertoires autorisés. Un site piraté reste un site piraté au lieu de se transformer en accès à toute la machine — et c’est précisément ce passage qui constitue l’essentiel du dommage.
Un ordre d’adoption raisonnable : d’abord un profil pour ce qui regarde vers l’internet (serveur web, PHP-FPM), puis pour les bases de données, ensuite selon les besoins. Il n’est pas nécessaire de tout activer d’un coup, et il n’existe pas de jeu universel tout prêt : un profil dépend de l’endroit où vivent vos fichiers.
Ce qu’il faut vérifier régulièrement
Les profils retombent en mode non confiné plus souvent qu’on ne croit : une mise à jour de paquet peut remplacer un fichier de profil, un débogage manuel laisse un service en complain, et un nouveau service arrive sans aucun profil. Deux chiffres sont utiles : combien de profils sont en enforce et combien de processus réseau sont sans restriction. Une variation de l’un ou de l’autre mérite d’être connue. À quoi cela ressemble rassemblé sur une page, la démonstration ci-dessous le montre.