La sécurité d’un système Linux repose sur plusieurs couches complémentaires. Si le pare-feu filtre le trafic réseau et les permissions Unix contrôlent l’accès aux fichiers, ces mécanismes restent insuffisants face à une application compromise. Un processus s’exécutant avec les droits de son propriétaire peut accéder à n’importe quelle ressource autorisée par ces droits — souvent bien plus que ce dont il a réellement besoin. C’est précisément le problème qu’AppArmor résout.
AppArmor est un module de sécurité Linux (LSM) qui implémente un contrôle d’accès obligatoire (Mandatory Access Control, MAC). Contrairement au contrôle d’accès discrétionnaire (DAC) classique, AppArmor associe à chaque programme un profil définissant précisément les fichiers, capacités et ressources auxquels il est autorisé à accéder — indépendamment de l’identité de l’utilisateur qui le lance. Si une application est compromise, l’attaquant reste confiné dans les limites du profil.
AppArmor est intégré par défaut dans le noyau Debian depuis Buster (10) et dans toutes les versions modernes d’Ubuntu. Contrairement à SELinux (qui fonctionne sur des étiquettes inode), AppArmor travaille sur les chemins de fichiers, ce qui le rend plus simple à appréhender et à administrer au quotidien. Ce guide couvre l’installation, la création de profils, les modes de fonctionnement et les bonnes pratiques opérationnelles.
Principes et architecture
AppArmor s’intègre directement dans le noyau Linux via le framework LSM. À chaque appel système, le noyau interroge AppArmor pour déterminer si le processus appelant est autorisé à effectuer l’opération demandée. En cas de refus, l’appel système retourne une erreur de permission et l’événement est journalisé.
Un profil AppArmor est un fichier texte stocké dans /etc/apparmor.d/. Son nom suit la convention du chemin complet de l’exécutable avec les / remplacés par des points (ex : /etc/apparmor.d/usr.sbin.nginx pour /usr/sbin/nginx). Chaque profil est compilé par apparmor_parser et chargé dans le noyau.
Modes de fonctionnement
AppArmor propose trois états pour chaque profil :
- enforce — le profil est actif : les violations sont bloquées et journalisées. C’est le mode de production.
- complain — le profil est en apprentissage : les violations sont journalisées mais non bloquées. Indispensable pour développer et affiner un nouveau profil.
- disabled — le profil est déchargé du noyau : aucune restriction n’est appliquée à l’application.
Les règles
denyexplicites dans un profil restent appliquées même en mode complain. Seules les règles d’autorisation manquantes sont journalisées sans bloquer.
Installation et vérification
Sur Debian et Ubuntu récents, AppArmor est actif dès l’installation. Vérifiez son état avec :
# Vérifier qu'AppArmor est bien chargé par le noyau (retourne "Y" si actif)
cat /sys/module/apparmor/parameters/enabled
# Afficher le statut détaillé : profils chargés, modes, processus confinés
sudo aa-status
La sortie d’aa-status liste le nombre de profils en mode enforce et complain, ainsi que les processus actuellement confinés. Installez les outils de gestion et les profils communautaires :
# Installer les utilitaires AppArmor et les profils additionnels
sudo apt install apparmor-utils apparmor-profiles apparmor-profiles-extra
# Vérifier que le service est actif et démarre au boot
sudo systemctl status apparmor
Structure d’un profil AppArmor
Un profil se compose d’une en-tête, d’inclusions d’abstractions et de règles d’accès. Voici la structure de base pour un service web Nginx :
# /etc/apparmor.d/usr.sbin.nginx — exemple de profil pour Nginx
#include <tunables/global>
/usr/sbin/nginx {
# Abstractions : groupes de règles prédéfinies réutilisables
#include <abstractions/base>
#include <abstractions/nameservice>
# Capacités POSIX nécessaires au démarrage en tant que root
capability net_bind_service, # Écouter sur les ports < 1024
capability setuid,
capability setgid,
# Accès aux fichiers : r=lecture, w=écriture, x=exécution
/etc/nginx/** r, # Configuration (lecture seule)
/var/www/** r, # Contenu web (lecture seule)
/var/log/nginx/** rw, # Logs (lecture/écriture)
/run/nginx.pid rw, # PID file
# Accès réseau
network inet stream,
network inet6 stream,
# Refus explicite de l'écriture dans /proc
deny /proc/** w,
}
Les abstractions sont stockées dans /etc/apparmor.d/abstractions/. Elles regroupent les règles communes à de nombreuses applications (accès à la libc, résolution DNS, accès aux certificats, etc.) et simplifient considérablement la rédaction des profils. Utilisez-les systématiquement plutôt que de dupliquer des règles.
Tableau des permissions
r— lecturew— écriture (inclut l’ajout et la troncature)x— exécutionm— mappage mémoire exécutable (mmap avec PROT_EXEC)k— verrouillage de fichier (flock, fcntl)l— création de liens physiques (hard links)
Créer un profil avec aa-genprof
aa-genprof est l’outil principal pour générer un profil à partir du comportement réel d’une application. Il fonctionne en deux phases : observation en mode complain, puis génération interactive des règles depuis les logs.
# Lancer aa-genprof sur le binaire cible
# AppArmor place automatiquement l'application en mode complain
sudo aa-genprof /usr/sbin/mon-service
Pendant que aa-genprof est en attente, exercez l’application dans tous ses cas d’usage légitimes : démarrage, arrêt, traitement de requêtes, rotation de logs, rechargement de configuration, accès base de données. Plus la couverture est complète, plus le profil généré sera précis et éviter des violations en production.
Appuyez sur S dans aa-genprof pour analyser les logs et répondre aux propositions de règles (autoriser, refuser, ignorer). Une fois toutes les règles confirmées, appuyez sur F pour finaliser le profil.
# Après génération, consulter le profil créé
cat /etc/apparmor.d/usr.sbin.mon-service
# Passer le profil en mode enforce pour la production
sudo aa-enforce /etc/apparmor.d/usr.sbin.mon-service
# Recharger le service AppArmor pour activer le nouveau profil
sudo systemctl reload apparmor
Affiner un profil avec aa-logprof
Même après une session aa-genprof soigneuse, des violations apparaîtront lors de l’utilisation en production (cas limites, tâches planifiées, mises à jour). aa-logprof analyse les logs et propose des mises à jour :
# Analyser les violations enregistrées et mettre à jour les profils interactivement
sudo aa-logprof
# Spécifier un fichier de log alternatif
sudo aa-logprof -f /var/log/syslog
La commande liste chaque violation, identifie la ressource concernée et propose plusieurs options. Répondez à chaque proposition, sauvegardez, puis rechargez le profil modifié.
Gestion courante des profils
Commandes de référence
# Lister tous les profils chargés et leur mode
sudo aa-status
# Passer un profil en mode complain (développement/test)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# Passer un profil en mode enforce (production)
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
# Désactiver un profil (crée un lien symbolique dans disable/)
sudo aa-disable /etc/apparmor.d/usr.sbin.nginx
# Recharger un profil après modification manuelle
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
# Recharger tous les profils en une commande
sudo systemctl reload apparmor
# Identifier les processus réseau sans profil AppArmor actif
sudo aa-unconfined --paranoid
Lire et interpréter les logs de violation
# Consulter les violations AppArmor dans le journal systemd
sudo journalctl -k | grep apparmor
# Filtrer uniquement les refus (DENIED) dans syslog
sudo grep 'apparmor="DENIED"' /var/log/syslog
# Surveiller les violations en temps réel
sudo tail -f /var/log/syslog | grep apparmor
Un message de violation typique ressemble à :
apparmor="DENIED" operation="open" profile="/usr/sbin/nginx"
name="/etc/passwd" pid=1234 comm="nginx"
requested_mask="r" denied_mask="r" fsuid=33 ouid=0
Ce message indique que nginx (pid 1234) a tenté d’ouvrir /etc/passwd en lecture, ce qui a été refusé par son profil. Si ce comportement est légitime (ex : résolution d’utilisateurs), ajoutez la règle /etc/passwd r, au profil puis rechargez-le.
AppArmor et conteneurs
AppArmor fonctionne nativement avec Docker et Podman. Docker applique automatiquement le profil docker-default à chaque conteneur. Vous pouvez spécifier un profil personnalisé au lancement :
# Lancer un conteneur avec un profil AppArmor personnalisé
docker run --security-opt apparmor=mon-profil-nginx nginx:latest
# Désactiver AppArmor pour un conteneur spécifique (déconseillé en production)
docker run --security-opt apparmor=unconfined mon-image
# Vérifier le profil appliqué à un conteneur en cours d'exécution
docker inspect --format='{{.HostConfig.SecurityOpt}}' mon-conteneur
Pour Podman en mode rootless (voir notre article dédié sur Podman), AppArmor est supporté sur Ubuntu. Cette combinaison renforce significativement l’isolation des workloads conteneurisés : même si un attaquant s’échappe de l’espace de noms utilisateur, le profil AppArmor limite les dégâts au niveau du noyau.
Bonnes pratiques opérationnelles
- Commencer par le mode complain — ne jamais passer directement en enforce sur un nouveau profil. Exercez l’application dans tous ses cas d’usage, analysez les logs avec
aa-logprof, itérez jusqu’à zéro violation avant de basculer. - Versionner les profils — les profils sont de simples fichiers texte : les gérer avec git ou un outil comme Ansible garantit la cohérence entre serveurs et la traçabilité des modifications.
- Auditer les processus non confinés — exécuter périodiquement
aa-unconfined --paranoidpour identifier les services réseau sans profil actif. - Utiliser les abstractions — exploiter les abstractions existantes (
abstractions/base,abstractions/ssl_certs, etc.) pour des profils concis et maintenables. - Défense en profondeur — AppArmor se combine avec le filtrage réseau nftables et les paramètres sysctl de durcissement pour une sécurité en profondeur (defense in depth).
À lire également
- nftables en pratique — remplacer iptables sur Debian/Ubuntu — complémentez le confinement applicatif AppArmor avec un filtrage réseau granulaire via nftables.
- Podman : alternative rootless à Docker — installation et migration — AppArmor renforce l’isolation des conteneurs Podman en mode rootless pour des workloads sans privilèges.
- Tuning kernel Linux — paramètres sysctl essentiels pour la production — paramètres sysctl de durcissement qui complètent la politique AppArmor au niveau du noyau.
- Sécurité Linux — Firewall iptables et nftables — les fondamentaux du filtrage réseau Linux, à combiner avec AppArmor pour une défense en profondeur.