Partager via


Accès du conteneur de sécurité aux ressources à l’aide des fonctionnalités de sécurité Linux intégrées

Dans cet article, vous allez apprendre à sécuriser l’accès des conteneurs aux ressources pour vos charges de travail Azure Kubernetes Service (AKS).

Vue d’ensemble

De la même façon que vous devez accorder aux utilisateurs ou aux groupes le minimum de privilèges requis, vous devez limiter les conteneurs uniquement aux actions et processus nécessaires. Pour réduire le risque d’attaque, évitez de configurer les applications et les conteneurs qui nécessitent une escalade des privilèges ou un accès racine.

Vous pouvez utiliser des contextes de sécurité de pod Kubernetes intégrés pour définir davantage d’autorisations, telles que l’utilisateur ou le groupe à exécuter, les fonctionnalités Linux à exposer ou définir des allowPrivilegeEscalation: false dans le manifeste de pod. Pour plus de meilleures pratiques, consultez Sécuriser l’accès du pod aux ressources.

Pour un contrôle encore plus précis des actions de conteneur, vous pouvez utiliser des fonctionnalités de sécurité Linux intégrées telles que AppArmor et seccomp.

  1. Définissez les fonctionnalités de sécurité de Linux au niveau du nœud.
  2. Implémentez les fonctionnalités par le biais d’un manifeste de pod.

Les fonctionnalités de sécurité Linux intégrées sont disponibles sur les nœuds et les pods Linux uniquement.

Remarque

Actuellement, les environnements Kubernetes ne sont pas totalement sûrs pour une utilisation multilocataire hostile. D’autres fonctionnalités de sécurité, comme Microsoft Defender pour les conteneurs, AppArmor, seccomp, Pod Security Admission ou RBAC Kubernetes pour les nœuds, bloquent efficacement les attaques.

Pour une véritable sécurité lors de l’exécution de charges de travail multilocataires hostiles, ne faites confiance qu’à un hyperviseur. Le domaine de sécurité de Kubernetes devient le cluster, et non un nœud individuel.

Pour ces types de charges de travail multilocataires hostiles, vous devez utiliser des clusters physiquement isolés.

AppArmor

Pour limiter les actions de conteneurs, vous pouvez utiliser le module de sécurité du noyau Linux AppArmor. AppArmor est disponible dans le cadre du système d’exploitation de nœud AKS sous-jacent et est activé par défaut. Vous créez des profils AppArmor qui limitent les actions de lecture, d’écriture ou d’exécution, ou des fonctions système telles que le montage de systèmes de fichiers. Les profils AppArmor par défaut limitent l’accès à divers emplacements /proc et /sys, et fournissent un moyen pour isoler de façon logique les conteneurs à partir du nœud sous-jacent. AppArmor fonctionne pour n’importe quelle application qui s’exécute sur Linux, pas seulement les pods Kubernetes.

Profils AppArmor en cours d’utilisation dans un cluster AKS pour limiter les actions de conteneur

Pour voir AppArmor en action, l’exemple suivant crée un profil qui empêche l’écriture de fichiers.

  1. SSH vers un nœud AKS.

  2. Créez un fichier nommé deny-write.profile.

  3. Copiez et collez le contenu suivant :

    #include <tunables/global>
    profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
      #include <abstractions/base>
    
      file,
      # Deny all file writes.
      deny /** w,
    }
    

Les profils AppArmor sont ajoutés à l’aide de la commande apparmor_parser.

  1. Ajoutez le profil à AppArmor.

  2. Spécifiez le nom du profil créé à l’étape précédente :

    sudo apparmor_parser deny-write.profile
    

    Si le profil est analysé correctement et appliqué à AppArmor, vous ne verrez aucune sortie et vous serez redirigé vers l’invite de commandes.

  3. À partir de votre machine locale, créez un manifeste de pod nommé aks-apparmor.yaml. Ce manifeste :

    • Définit une annotation pour container.apparmor.security.beta.kubernetes.
    • Référence le profil deny-write créé aux étapes précédentes.
    apiVersion: v1
    kind: Pod
    metadata:
      name: hello-apparmor
      annotations:
        container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write
    spec:
      containers:
      - name: hello
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
    
  4. Une fois le pod déployé, exécutez la commande suivante et vérifiez que le pod hello-apparmor affiche un état En cours d’exécution :

    kubectl get pods
    
    NAME             READY   STATUS    RESTARTS   AGE
    aks-ssh          1/1     Running   0          4m2s
    hello-apparmor   0/1     Running   0          50s
    

Pour plus d’informations sur AppArmor, consultez les Profils AppArmor dans Kubernetes.

Sécuriser le calcul (seccomp)

Tandis qu’AppArmor fonctionne pour toutes les applications Linux, seccomp (secure computing) agit au niveau du processus. Seccomp est également un module de sécurité du noyau Linux, pris en charge de façon native par le runtime containerd utilisé par les nœuds AKS. Avec seccomp, vous pouvez limiter les appels au système d’un conteneur. Seccomp établit une couche supplémentaire de protection contre les vulnérabilités d’appel système courantes exploitées par des acteurs malveillants et vous permet de spécifier un profil par défaut pour toutes les charges de travail du nœud.

Configurer un profil seccomp par défaut (préversion)

Vous pouvez appliquer des profils seccomp par défaut à l’aide de configurations de nœuds personnalisées lors de la création d’un pool de nœuds Linux. Il existe deux valeurs prises en charge sur AKS : RuntimeDefault et Unconfined. Certaines charges de travail peuvent nécessiter un nombre inférieur de restrictions syscall que d’autres. Cela signifie qu’elles peuvent échouer pendant l’exécution avec le profil « RuntimeDefault ». Pour atténuer ce type d’échec, vous pouvez spécifier le profil Unconfined . Si votre charge de travail nécessite un profil personnalisé, consultez Configurer un profil seccomp personnalisé.

Limites

  • SeccompDefault n’est pas un paramètre pris en charge pour les pools de nœuds Windows.
  • SeccompDefault est disponible à partir de l’API 2024-09-02-preview.

Important

Les fonctionnalités d’évaluation AKS sont disponibles en libre-service et font l’objet d’un abonnement. Les préversions sont fournies « en l’état » et « en fonction des disponibilités », et sont exclues des contrats de niveau de service et de la garantie limitée. Les préversions AKS sont, dans la mesure du possible, partiellement couvertes par le service clientèle. Telles quelles, ces fonctionnalités ne sont pas destinées à une utilisation en production. Pour plus d’informations, consultez les articles de support suivants :

Inscrire l’indicateur de fonctionnalité KubeletDefaultSeccompProfilePreview

  1. Inscrivez l’indicateur de fonctionnalité KubeletDefaultSeccompProfilePreview à l’aide de la commande az feature register.

    az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    

    Quelques minutes sont nécessaires pour que l’état s’affiche Registered (Inscrit).

  2. Vérifiez l’état de l’inscription en utilisant la commande az feature show.

    az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    
  3. Quand l’état reflète Inscrit, actualisez l’inscription du fournisseur de ressources Microsoft.ContainerService à l’aide de la commande az provider register.

    az provider register --namespace Microsoft.ContainerService
    

Restreindre les appels système de votre conteneur avec seccomp

1. Suivez les étapes pour appliquer un profil seccomp dans votre configuration kubelet en spécifiant "seccompDefault": "RuntimeDefault".

RuntimeDefault utilise le profil seccomp de containerD par défaut, qui restreint certains appels système afin d’améliorer la sécurité. Les syscalls restreints échoueront. Pour plus de détails, consultez le profil seccomp de containerD par défaut.

2. Vérifiez que la configuration a été appliquée.

Vous pouvez confirmer que les paramètres sont appliqués aux nœuds. Pour cela, connectez-vous à l’hôte et validez que les modifications de la configuration ont été apportées au système de fichiers.

3. Résoudre les problèmes de défaillances des charges de travail.

Lorsque SeccompDefault est activé, le profil seccomp par défaut du runtime de conteneur est utilisé par défaut pour toutes les charges de travail planifiées sur le nœud. Cela peut entraîner l’échec des charges de travail en raison de syscalls bloqués. Si une défaillance de charge de travail s’est produite, vous pouvez voir des erreurs telles que :

  • La charge de travail est existante de façon inattendue une fois que la fonctionnalité est activée, avec l’erreur « autorisation refusée ».
  • Les messages d’erreur Seccomp peuvent également être affichés dans audité ou syslog en remplaçant SCMP_ACT_ERRNO par SCMP_ACT_LOG dans le profil par défaut.

Si vous rencontrez les erreurs ci-dessus, nous vous recommandons de modifier votre profil seccomp par Unconfined. Unconfined n’impose aucune restriction sur les syscalls, en autorisant tous les appels système, ce qui réduit la sécurité.

Configurer un profil seccomp personnalisé

Avec un profil seccomp personnalisé, vous pouvez avoir un contrôle plus précis sur les syscalls restreints. Respectez la bonne pratique consistant à accorder l’autorisation minimale au conteneur pour une exécution en :

  • Définissant avec des filtres les actions à autoriser ou à refuser.
  • Annotant dans un manifeste YAML de pod afin d’associer au filtre seccomp.

Pour voir seccomp en action, créez un filtre qui empêche la modification des autorisations sur un fichier.

  1. SSH vers un nœud AKS.

  2. Créez un filtre seccomp nommé /var/lib/kubelet/seccomp/prevent-chmod.

  3. Copiez et collez le contenu suivant :

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "name": "chmod",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "fchmodat",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "chmodat",
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    

    Dans les versions 1.19 et ultérieures, vous devez configurer :

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "names": ["chmod","fchmodat","chmodat"],
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    
  4. À partir de votre machine locale, créez un manifeste de pod nommé aks-seccomp.yaml et collez le contenu suivant. Ce manifeste :

    • Définit une annotation pour seccomp.security.alpha.kubernetes.io.
    • Référence le filtre prevent-chmod créé à l’étape précédente.
    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod
    spec:
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    

    Dans les versions 1.19 et ultérieures, vous devez configurer :

    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
    spec:
      securityContext:
        seccompProfile:
          type: Localhost
          localhostProfile: prevent-chmod
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    
  5. Déployez l’exemple de pod à l’aide de la commande kubectl apply :

    kubectl apply -f ./aks-seccomp.yaml
    
  6. Affichez l’état du pod à l’aide de la commande kubectl get pods.

    • Le pod signale une erreur.
    • La commande chmod ne peut pas être exécutée en raison du filtre seccomp, comme affiché dans l’exemple de sortie :
    kubectl get pods
    
    NAME                      READY     STATUS    RESTARTS   AGE
    chmod-prevented           0/1       Error     0          7s
    

Options de profil de sécurité Seccomp

Les profils de sécurité Seccomp sont un ensemble de syscalls définis autorisés ou restreints. La plupart des runtimes de conteneur ont un profil seccomp par défaut similaire si ce n’est pas le même que celui qu’utilise Docker. Pour plus d’informations sur les profils disponibles, consultez profils Docker ou containerD profils seccomp par défaut.

AKS utilise le profil containerD seccomp par défaut pour notre runtimeDefault lorsque vous configurez seccomp à l’aide de la configuration de nœud personnalisée.

Syscalls significatifs bloqués par profil par défaut

Docker et containerD conservent les listes d’autorisation des syscalls sécurisés. Ce tableau répertorie les syscalls importants (mais pas tous) qui sont effectivement bloqués, car ils ne figurent pas sur la liste d’autorisation. Si l’un des syscalls bloqués est requis par votre charge de travail, n’utilisez pas le profil RuntimeDefault seccomp.

Lorsque des modifications sont apportées à docker et conteneurD, AKS met à jour sa configuration par défaut pour qu’elle corresponde. Les mises à jour apportées à cette liste peuvent entraîner une défaillance de la charge de travail. Pour des mises à jour de versions, consultez les notes de publication relatives à AKS.

Syscall bloqué Description
acct Syscall de comptabilité qui peut permettre aux conteneurs de désactiver leurs propres limites de ressources ou de traiter la comptabilité. Également contrôlé par CAP_SYS_PACCT.
add_key Empêcher les conteneurs d’utiliser le porte-clés du noyau, qui n’est pas espace de noms.
bpf Refuser le chargement de programmes bpf potentiellement persistants dans le noyau, déjà contrôlé par CAP_SYS_ADMIN.
clock_adjtime L’heure/la date n’a pas espace de noms. Également contrôlé par CAP_SYS_TIME.
clock_settime L’heure/la date n’a pas espace de noms. Également contrôlé par CAP_SYS_TIME.
clone Refuser le clonage de nouveaux espaces de noms. Également contrôlé par les indicateurs CAP_SYS_ADMIN for CLONE_*, sauf CLONE_NEWUSER.
create_module Refuser la manipulation et les fonctions sur les modules du noyau. Obsolète. Également contrôlé par CAP_SYS_MODULE.
delete_module Refuser la manipulation et les fonctions sur les modules du noyau. Également contrôlé par CAP_SYS_MODULE.
finit_module Refuser la manipulation et les fonctions sur les modules du noyau. Également contrôlé par CAP_SYS_MODULE.
get_kernel_syms Refuser la récupération des symboles de noyau et de module exportés. Obsolète.
get_mempolicy Syscall qui modifie la mémoire du noyau et les paramètres NUMA. Déjà contrôlé par CAP_SYS_NICE.
init_module Refuser la manipulation et les fonctions sur les modules du noyau. Également contrôlé par CAP_SYS_MODULE.
ioperm Empêcher les conteneurs de modifier les niveaux de privilèges d’E/S du noyau. Déjà contrôlé par CAP_SYS_RAWIO.
iopl Empêcher les conteneurs de modifier les niveaux de privilèges d’E/S du noyau. Déjà contrôlé par CAP_SYS_RAWIO.
kcmp Restreindre les fonctionnalités d’inspection des processus, déjà bloquées en supprimant CAP_SYS_PTRACE.
kexec_file_load Syscall sœur de kexec_load qui fait la même chose, arguments légèrement différents. Également contrôlé par CAP_SYS_BOOT.
kexec_load Refuser le chargement d’un nouveau noyau pour une exécution ultérieure. Également contrôlé par CAP_SYS_BOOT.
keyctl Empêcher les conteneurs d’utiliser le porte-clés du noyau, qui n’est pas espace de noms.
lookup_dcookie Suivi/profilage syscall, qui pourrait fuiter des informations sur l’hôte. Également contrôlé par CAP_SYS_ADMIN.
mbind Syscall qui modifie la mémoire du noyau et les paramètres NUMA. Déjà contrôlé par CAP_SYS_NICE.
mount Refuser le montage, déjà contrôlé par CAP_SYS_ADMIN.
move_pages Syscall qui modifie la mémoire du noyau et les paramètres NUMA.
nfsservctl Refuser l’interaction avec le démon nfs du noyau. Obsolète depuis Linux 3.1.
open_by_handle_at Cause d’un ancien petit groupe de conteneurs. Également contrôlé par CAP_DAC_READ_SEARCH.
perf_event_open Suivi/profilage syscall, qui pourrait fuiter des informations sur l’hôte.
personality Empêcher le conteneur d’activer l’émulation BSD. Pas intrinsèquement dangereux, mais mal testé, potentiel pour les vulns de noyau.
pivot_root Refuser pivot_root, doit être une opération privilégiée.
process_vm_readv Restreindre les fonctionnalités d’inspection des processus, déjà bloquées en supprimant CAP_SYS_PTRACE.
process_vm_writev Restreindre les fonctionnalités d’inspection des processus, déjà bloquées en supprimant CAP_SYS_PTRACE.
ptrace Suivi/profilage de syscall. Bloqué dans les versions du noyau Linux avant la version 4.8 pour éviter le contournement seccomp. Les processus arbitraires de suivi/profilage sont déjà bloqués en supprimant CAP_SYS_PTRACE, car ils pourraient fuiter des informations sur l’hôte.
query_module Refuser la manipulation et les fonctions sur les modules du noyau. Obsolète.
quotactl Syscall de quota qui pourrait permettre aux conteneurs de désactiver leurs propres limites de ressources ou de traiter la comptabilité. Également contrôlé par CAP_SYS_ADMIN.
reboot Ne laissez pas les conteneurs redémarrer l’hôte. Également contrôlé par CAP_SYS_BOOT.
request_key Empêcher les conteneurs d’utiliser le porte-clés du noyau, qui n’est pas espace de noms.
set_mempolicy Syscall qui modifie la mémoire du noyau et les paramètres NUMA. Déjà contrôlé par CAP_SYS_NICE.
setns Refuser l’association d’un thread à un espace de noms. Également contrôlé par CAP_SYS_ADMIN.
settimeofday L’heure/la date n’a pas espace de noms. Également contrôlé par CAP_SYS_TIME.
stime L’heure/la date n’a pas espace de noms. Également contrôlé par CAP_SYS_TIME.
swapon Refuser le démarrage/arrêter l’échange vers le fichier/l’appareil. Également contrôlé par CAP_SYS_ADMIN.
swapoff Refuser le démarrage/arrêter l’échange vers le fichier/l’appareil. Également contrôlé par CAP_SYS_ADMIN.
sysfs Syscall obsolète.
_sysctl Obsolète, remplacé par /proc/sys.
umount Doit être une opération privilégiée. Également contrôlé par CAP_SYS_ADMIN.
umount2 Doit être une opération privilégiée. Également contrôlé par CAP_SYS_ADMIN.
unshare Refuser le clonage de nouveaux espaces de noms pour les processus. Également contrôlé par CAP_SYS_ADMIN, à l’exception d’unshare --user.
uselib Ancien syscall lié aux bibliothèques partagées, inutilisé pendant une longue période.
userfaultfd Gestion des erreurs de page Userspace, largement nécessaire pour la migration de processus.
ustat Syscall obsolète.
vm86 Dans la machine virtuelle en mode réel x86 du noyau. Également contrôlé par CAP_SYS_ADMIN.
vm86old Dans la machine virtuelle en mode réel x86 du noyau. Également contrôlé par CAP_SYS_ADMIN.

Étapes suivantes

Pour connaître les meilleures pratiques associées, voir Meilleures pratiques relatives aux mises à jour et à la sécurité du cluster dans AKS et Bonnes pratiques relatives à la sécurité de pod dans AKS.