Sécuriser des conteneurs avec AppArmor

AppArmor est un module de sécurité du noyau Linux que vous pouvez utiliser pour limiter les fonctionnalités des processus s'exécutant sur le système d'exploitation hôte. Chaque processus peut avoir son propre profil de sécurité. Le profil de sécurité autorise ou non les fonctionnalités spécifiques, telles que l'accès au réseau ou les autorisations de lecture, écriture et exécution de fichiers.

Vous pouvez utiliser AppArmor avec les conteneurs Docker s'exécutant sur vos instances Container-Optimized OS. Pour tout conteneur donné, vous pouvez appliquer le profil de sécurité AppArmor par défaut fourni avec Docker ou un profil de sécurité personnalisé que vous fournissez.

Utiliser le profil de sécurité AppArmor par défaut de Docker

Lorsque vous démarrez un conteneur sur votre instance Container-Optimized OS, le système applique automatiquement le profil de sécurité AppArmor docker-default. L'exemple de commande suivant exécute un conteneur avec le profil de sécurité docker-default :

docker run --rm -it debian:jessie bash -i

Pour tester le profil de sécurité docker-default, vous pouvez essayer de lire le fichier /proc/sysrq-trigger avec la commande cat, comme suit :

root@88cef496c1a5:/# cat /proc/sysrq-trigger

Le résultat doit contenir une erreur de type "Permission Denied" (Autorisation refusée) semblable à celle-ci :

cat: /proc/sysrq-trigger: Permission denied

Attribuer un profil de sécurité personnalisé

Pour appliquer un autre profil de sécurité, utilisez l'option de ligne de commande apparmor=<profile-name> lorsque vous exécutez votre conteneur. L'exemple de commande suivant exécute un conteneur avec un profil de sécurité appelé no-ping :

docker run --rm -i --security-opt apparmor=no-ping debian:jessie bash -i

Consultez la section Créer un profil de sécurité personnalisé plus loin dans cette rubrique pour plus d'informations sur la création du profil no-ping spécifié dans l'exemple.

Vous pouvez également spécifier unconfinedavec l'option apparmor pour indiquer que le conteneur doit être exécuté sans profil de sécurité, comme dans l'exemple suivant :

docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i

Afficher les profils de sécurité AppArmor actifs

Vous pouvez voir quel profil AppArmor, le cas échéant, s'applique aux processus sur votre instance Container-Optimized OS en inspectant le fichier /proc/<pid>/attr/current, dans lequel <pid> est l'ID du processus.

Supposons que les processus suivants soient exécutés sur votre instance (ces processus sont affichés avec la commande ps -ef | grep '[b]ash -i') :

root      1903  1897  0 21:58 pts/3    00:00:00 docker run --rm -it debian:jessie bash -i
root      1927  1913  0 21:58 pts/4    00:00:00 bash -i
root      1978  1001  0 22:01 pts/0    00:00:00 docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
root      2001  1988  0 22:01 pts/2    00:00:00 bash -i

Si vous inspectez /proc/1927/attr/current, vous devriez obtenir le résultat suivant qui indique que le processus (pid 1927) a été exécuté avec le profil de sécurité Docker par défaut :

# cat /proc/1927/attr/current
docker-default (enforce)

Si vous inspectez /proc/2001/attr/current, vous devriez obtenir le résultat suivant qui indique que le processus (pid 2001) a été exécuté sans profil de sécurité (c'est-à-dire, avec l'option apparmor=unconfined) :

# cat /proc/2001/attr/current
unconfined

Créer un profil de sécurité personnalisé

Si un processus implique un profil de sécurité différent de docker-default, vous pouvez écrire votre propre profil personnalisé. Pour utiliser un profil personnalisé, vous devez créer le fichier de profil, puis le charger dans AppArmor.

Par exemple, supposons que vous souhaitiez un profil de sécurité qui interdit tout le trafic réseau brut. Le script suivant crée un fichier pour un profil de sécurité appelé no-ping dans /etc/apparmor.d/no_raw_net :

cat > /etc/apparmor.d/no_raw_net <<EOF
#include <tunables/global>

profile no-ping flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>

  network inet tcp,
  network inet udp,
  network inet icmp,

  deny network raw,
  deny network packet,
  file,
  mount,
}
EOF

Après avoir créé le fichier de profil de sécurité, vous pouvez utiliser apparmor_parser pour charger le profil dans AppArmor :

/sbin/apparmor_parser --replace --write-cache /etc/apparmor.d/no_raw_net

Une fois le profil no-ping chargé, vous pouvez le tester comme suit :

$ docker run --rm -i --security-opt apparmor=no-ping debian:jessie ping -c3 8.8.8.8

La commande crée un conteneur avec le profil de sécurité no-ping et tente d'exécuter ping à partir du conteneur. Le profil de sécurité doit interdire le trafic, ce qui entraîne une erreur semblable à celle-ci :

ping: Lacking privilege for raw socket.

Pour vous assurer que votre profil de sécurité personnalisé est présent au démarrage de votre instance Container-Optimized OS et qu'il reste persistant après le redémarrage, vous pouvez utiliser cloud-init pour installer le profil dans /etc/apparmor.d. Pour ce faire, ajoutez un script cloud-config aux métadonnées de votre instance en tant que valeur de la clé user-data.

Le script cloud-config suivant ajoute le profil no-ping à /etc/apparmor.d :

#cloud-configs

write_files:
- path: /etc/apparmor.d/no_raw_net
  permissions: 0644
  owner: root
  content: |
    #include <tunables/global>

    profile no-ping flags=(attach_disconnected,mediate_deleted) {
      #include <abstractions/base>

      network inet tcp,
      network inet udp,
      network inet icmp,

      deny network raw,
      deny network packet,
      file,
      mount,
    }

Pour vous assurer que votre fichier de service charge bien votre profil personnalisé dans AppArmor et indique à Docker de l'utiliser, exécutez les commandes suivantes sur votre instance :

ExecStartPre=/sbin/apparmor_parser -r -W /etc/apparmor.d/no_raw_net
ExecStart=/usr/bin/docker run --security-opt apparmor=no-ping ...

Une fois que vous avez exécuté les commandes, redémarrez votre instance. Vous pouvez ensuite exécuter votre conteneur régi par votre profil AppArmor personnalisé.