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.
- Définissez les fonctionnalités de sécurité de Linux au niveau du nœud.
- 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.
Pour voir AppArmor en action, l’exemple suivant crée un profil qui empêche l’écriture de fichiers.
SSH vers un nœud AKS.
Créez un fichier nommé deny-write.profile.
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
.
Ajoutez le profil à AppArmor.
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.
À 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" ]
- Définit une annotation pour
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
Inscrivez l’indicateur de fonctionnalité
KubeletDefaultSeccompProfilePreview
à l’aide de la commandeaz feature register
.az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
Quelques minutes sont nécessaires pour que l’état s’affiche Registered (Inscrit).
Vérifiez l’état de l’inscription en utilisant la commande
az feature show
.az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
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.
SSH vers un nœud AKS.
Créez un filtre seccomp nommé /var/lib/kubelet/seccomp/prevent-chmod.
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" } ] }
À 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
- Définit une annotation pour
Déployez l’exemple de pod à l’aide de la commande kubectl apply :
kubectl apply -f ./aks-seccomp.yaml
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.
Azure Kubernetes Service