AppArmor sur Debian/Ubuntu : profils, modes et confinement applicatif

07 juin 2026 — par admin_libra

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 deny explicites 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 — lecture
  • w — écriture (inclut l’ajout et la troncature)
  • x — exécution
  • m — 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 --paranoid pour 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

Références

Index complet

Tous les articles (41)

Date Article Tags
07/06/2026 Docker : comment récupérer de l'espace disque cache conteneurs debian 07/06/2026 Graylog 7 — Centralisation et analyse de logs : l'alternative à ELK sur Debian/Ubuntu centralisation debian elk 07/06/2026 OpenZFS : tiering avec L2ARC et SLOG pour les workloads mixtes cache l2arc nvme 07/06/2026 Scripting Bash avancé — pièges, bonnes pratiques et optimisation automatisation bash bonnes-pratiques 07/06/2026 AppArmor sur Debian/Ubuntu : profils, modes et confinement applicatif apparmor audit confinement 07/06/2026 Durcissement SSH — au-delà des clés publiques 2fa authentification cryptographie 27/05/2026 LXD 6.x : orchestration de conteneurs Linux avec profils et clustering administration clustering conteneurs 27/05/2026 Keepalived — VIP flottante et load balancing sans matériel dédié debian failover haute-disponibilité 27/05/2026 Btrfs sur Linux — snapshots, sous-volumes et compression en pratique administration btrfs compression 21/05/2026 CVE-2026-42945 (NGINX Rift) : analyse et remédiation sur Debian/Ubuntu cve debian heap-overflow 21/05/2026 Tuning kernel Linux — paramètres sysctl essentiels pour la production debian kernel mémoire 21/05/2026 DRBD : réplication de blocs entre deux serveurs en temps réel cluster debian drbd 15/05/2026 CVE-2026-23918 — vulnérabilité Apache 2.4.66 : analyse et correctifs sur Debian/Ubuntu (hors Debian 11) apache cve debian 15/05/2026 CVE-2026-31431 (Copy Fail) — Analyse et remédiation sur Debian/Ubuntu algif_aead copy-fail cve 12/05/2026 Pacemaker et Corosync — cluster haute disponibilité Linux cluster corosync debian 12/05/2026 WireGuard : monter un VPN mesh entre plusieurs serveurs Linux chiffrement linux mesh 12/05/2026 Netdata — monitoring temps réel sans configuration complexe alertes dashboard linux 12/05/2026 nftables en pratique — remplacer iptables sur Debian/Ubuntu debian firewall iptables 12/05/2026 Podman : alternative rootless à Docker — installation et migration conteneurs docker kubernetes 02/05/2026 Prometheus et Grafana sur Debian — installation, configuration et dashboards pratiques alertmanager dashboard debian 02/05/2026 Ansible : automatiser la gestion de serveurs Linux avec des playbooks administration ansible automation 28/04/2026 ZFS sur Linux : snapshots, clones et RAID-Z en pratique administration compression filesystem 28/04/2026 eBPF sur Linux : observabilité et traçage kernel avec bpftrace et BCC bcc bpftrace diagnostic 23/04/2026 Analyse de la mémoire sur Linux — vmstat, free, smem diagnostic mémoire monitoring 23/04/2026 Sécurité Linux — Firewall iptables et nftables firewall iptables nftables 23/04/2026 ZFS sur Linux — Installation et gestion avancée administration filesystem stockage 23/04/2026 Gestion des services avec systemd sur Debian et Ubuntu administration debian services 23/04/2026 Gestion des ressources cgroups v1/v2 avec LXC cgroups conteneurs lxc 23/04/2026 Centralisation logs avec ELK Stack — Elasticsearch, Kibana, Filebeat elasticsearch elk filebeat 23/04/2026 Supervision avec Zabbix 7.0 LTS sur Debian/Ubuntu debian monitoring supervision 23/04/2026 Plusieurs versions PHP-FPM sur Apache Debian/Ubuntu apache debian php-fpm 23/04/2026 Sécurisation avancée PHP-FPM — Multi-VirtualHosts Apache/Nginx apache nginx php-fpm 23/04/2026 Optimisation PHP-FPM — Guide de tuning d'un pool optimisation performance php-fpm 29/07/2025 Docker sur Debian/Ubuntu : Installation, Configuration et Utilisation conteneurs debian docker 03/07/2025 Serveur VPN WireGuard sous linux réseau sécurité vpn 03/07/2025 Authentification par clé publique sur un serveur SSH authentification cryptographie sécurité 27/06/2025 Surveillance et diagnostic d’un serveur Linux avec vmstat, iotop et htop diagnostic htop monitoring 27/06/2025 Mémoire : Utilisation des Huge Pages et implémentation hugepages mémoire noyau 27/06/2025 Mémoire Swap et paramétrage swappiness mémoire noyau performance 18/06/2025 Installation et Configuration des Conteneurs LXC sur Linux administration conteneurs lxc 18/06/2025 Gestion des journaux avec syslog et journalctl administration journalctl logs