Réponse à incident Kubernetes avec les logs d'audit
Guide de réponse à incident Kubernetes : les preuves à collecter dans les logs d'audit, les questions à poser, les attaques à chercher et comment contenir.
TL;DR. Lors d'un incident Kubernetes, le log d'audit de l'API server est votre source de vérité : chaque kubectl exec, chaque lecture de secret, chaque nouveau binding et chaque nouveau workload est passé par l'API server, et chacun peut être enregistré avec qui, d'où, quoi et si c'était autorisé. Préservez d'abord les logs, puis répondez à cinq questions dans l'ordre : quelle identité, depuis quand, qu'a-t-elle touché, qu'a-t-elle laissé derrière elle, et que peut-elle encore atteindre. L'analyseur gratuit de logs d'audit dans le navigateur donne un premier verdict, des constats mappés sur MITRE ATT&CK et une chronologie sans rien envoyer ; la suite de ce guide explique ce qu'il y a derrière chaque étape.
Un incident Kubernetes commence rarement par une alerte qui dit « votre cluster est compromis ». Il commence par une facture cloud qui double, un nœud bloqué à 100 % de CPU, une règle Falco que personne n'a réglée, ou un token de compte de service retrouvé dans un dépôt public. À ce moment-là, il faut savoir vite si quelqu'un s'est réellement servi du cluster, et pour quoi faire.
Pourquoi le log d'audit est au centre de l'enquête
Toute modification d'un cluster, et la plupart des lectures, passent par l'API server Kubernetes. L'audit Kubernetes enregistre ces requêtes sous forme d'événements structurés : l'utilisateur authentifié et ses groupes, les IP sources, le user agent, le verbe, la ressource ciblée, le namespace, le nom et la sous-ressource, le code de réponse et, selon le niveau d'audit, le corps de la requête et de la réponse.
C'est donc le seul log qui couvre l'essentiel du travail d'un attaquant via le plan de contrôle :
| Étape de l'attaquant | Ce qu'on voit dans le log d'audit |
|---|---|
| Utilise un token volé | Requêtes d'un compte de service connu avec un user agent ou une IP source inhabituels |
| Vérifie ce que le token permet | Rafales de selfsubjectaccessreviews / selfsubjectrulesreviews (kubectl auth can-i) et réponses 403 |
| Vole des identifiants | list sur secrets sans namespace, nombreux get sur des secrets, requêtes serviceaccounts/token |
| Exécute des commandes | create / get sur pods/exec ou pods/attach, avec la commande dans requestURI |
| Élève ses privilèges | Nouveaux clusterrolebindings vers cluster-admin, rôles avec escalate / bind / impersonate |
| S'évade vers le nœud | Pods ou DaemonSets avec privileged: true, hostPID, un hostPath sur / |
| S'installe et monétise | CronJobs, DaemonSets dans kube-system, images de mineur |
| Efface ses traces | delete / deletecollection sur events |
Ce qu'il ne montre pas compte tout autant : les commandes tapées dans un shell une fois ouvert, les processus lancés sur un nœud après une évasion, le trafic entre pods. L'article sur les limites détaille ces angles morts et les sources runtime qui les comblent.
Étape 0 : préserver avant de toucher
Le réflexe est de supprimer le pod malveillant. Retenez-vous quelques minutes.
- Exportez les logs d'audit de toute la période et stockez-les hors du cluster. Sur les plateformes managées, ils sont dans CloudWatch Logs (EKS), Cloud Logging (GKE) ou Azure Monitor (AKS) ; le guide d'export EKS, GKE et AKS donne les commandes exactes. Vérifiez la rétention : les logs qui expirent demain sont les premiers à sauver.
- Sauvegardez les specs des objets suspects avec
kubectl get <kind> <name> -o yamlavant de les supprimer : DaemonSets, CronJobs, pods, ClusterRoleBindings, ServiceAccounts. - Faites un snapshot des disques des nœuds touchés si vous soupçonnez une évasion de conteneur. Un nœud remplacé emporte ses preuves avec lui.
- Notez ce que vous avez déjà fait, avec l'heure en UTC. Vos propres commandes
kubectlapparaîtront dans le même log d'audit.
Les recommandations d'AWS sur la réponse à incident et la forensique EKS et les mesures d'atténuation GKE de Google suivent le même ordre : isoler, préserver, puis remédier.
Étape 1 : une première lecture des logs
Un cluster produit beaucoup de bruit d'audit : kubelets qui renouvellent leurs leases, contrôleurs qui réconcilient, agents de supervision qui listent les pods toutes les quelques secondes. Lire des lignes JSON brutes n'est pas réaliste au-delà de quelques milliers d'événements.
Déposez l'export dans l'analyseur de logs d'audit Kubernetes. Il normalise les lignes JSON brutes audit.k8s.io/v1 et les formats d'export EKS, GKE et AKS en un seul modèle d'événement, applique 28 règles de détection relues, et renvoie :
- un verdict : « Compromission probable » dès qu'une règle critique ou trois règles élevées différentes se déclenchent, « Activité suspecte » pour une règle élevée ou deux règles moyennes, sinon « Aucun signe de compromission » ;
- des constats regroupés par identité ou par image, chacun avec une sévérité, un identifiant de technique ATT&CK et des étapes de remédiation ;
- une chronologie de l'incident où la première occurrence de chaque règle est mise en évidence ;
- un pivot par entité (utilisateurs et comptes de service, IP sources, namespaces, pods, images, user agents).
Tout s'exécute dans l'onglet du navigateur en WebAssembly ; les fichiers ne sont jamais envoyés. Le guide pas à pas passe en revue chaque panneau.
Un verdict sans signe de compromission n'est pas une preuve d'innocuité. Il signifie qu'aucune règle n'a matché dans les données fournies, et ces données dépendent fortement de votre politique d'audit.
Étape 2 : répondre aux cinq questions
Quelle identité ?
Partez du constat le plus sévère et notez le user.username. Un compte de service (system:serviceaccount:<namespace>:<name>) piloté avec kubectl/ ou curl/ comme user agent, ou depuis une IP publique, est presque toujours un token sorti de son pod. Une identité humaine qui fait quelque chose d'inhabituel mérite un appel à son propriétaire avant toute conclusion.
Gardez en tête que sourceIPs liste d'abord les en-têtes de proxy ; la référence des événements d'audit prévient que toutes les adresses sauf la dernière peuvent être fixées par le client.
Depuis quand ?
Filtrez les événements sur cette identité et sur ses IP sources, puis cherchez la requête la plus ancienne. Les attaquants font généralement de la reconnaissance (/version, /api, appels de découverte, auth can-i) avant toute action bruyante. Si le premier événement est au tout début de votre export, l'export est trop court : remontez plus loin.
Qu'a-t-elle touché ?
Listez tous les verbes et ressources de l'identité. Les secrets lus sont le plus urgent : chacun est un identifiant à faire tourner, et certains (clés cloud, tokens de CI, identifiants de registry) donnent accès à l'extérieur du cluster. Voir accès aux secrets et vol de tokens de compte de service.
Qu'a-t-elle laissé derrière elle ?
Cherchez les écritures : workloads, CronJobs, DaemonSets, ServiceAccounts, (Cluster)RoleBindings, Roles, webhooks, et nouveaux tokens émis via TokenRequest. Chacun est un moyen de revenir après la révocation du premier identifiant. L'article sur l'escalade RBAC couvre le côté bindings, l'article sur les pods privilégiés le côté nœuds.
Que peut-elle encore atteindre ?
Un cluster-admin capable de faire un exec dans un pod privilégié a pu lire les identifiants des nœuds, les rôles d'instance cloud et tous les secrets montés. Élargissez le périmètre au-delà du cluster : le compte cloud (CloudTrail, Cloud Audit Logs, Azure Activity Log), le système de CI, le registry. Pour le côté cloud, les sites frères AWS Forensics, GCP Forensics et Azure Forensics couvrent ces logs.
Étape 3 : contenir, éradiquer, restaurer
L'ordre compte, car certaines étapes en invalident d'autres.
- Coupez l'accès actuel de l'attaquant. Supprimez les bindings malveillants, supprimez puis recréez les comptes de service compromis (un token émis via TokenRequest reste valide jusqu'à son expiration sauf si le compte de service ou l'objet auquel il est lié est supprimé, comme l'explique la documentation des comptes de service), et restreignez qui peut joindre l'endpoint de l'API.
- Supprimez la persistance. Supprimez les DaemonSets, CronJobs, Jobs et pods malveillants, après avoir sauvegardé leurs specs, et cherchez des copies dans tous les namespaces.
- Reconstruisez les nœuds qui ont exécuté des pods privilégiés ou montant l'hôte. Cordon, drain, remplacement ; rotation des identifiants kubelet et cloud de l'instance.
- Faites tourner chaque secret qui a été lu.
- Fermez le point d'entrée : dashboard exposé, kubeconfig qui a fuité, token surprivilégié, accès anonyme.
- Durcissez et surveillez : Pod Security Admission sur chaque namespace, RBAC au moindre privilège, logs d'audit conservés hors du cluster. Le guide de durcissement Kubernetes de la NSA et de la CISA et la checklist de sécurité Kubernetes sont de bonnes bases.
La checklist de remédiation de l'analyseur suit cet ordre et ne liste que les étapes liées aux constats que vous avez réellement.
Mapper les constats sur ATT&CK, pas sur des outils
Le rapport est plus simple à écrire quand chaque constat porte un identifiant de technique. La matrice MITRE ATT&CK Containers couvre les étapes habituelles : T1609 Container Administration Command pour l'exec, T1610 Deploy Container, T1611 Escape to Host, T1552.007 Container API pour le vol de secrets, T1528 Steal Application Access Token, T1098.006 Additional Container Cluster Roles, T1053.007 Container Orchestration Job, T1496 Resource Hijacking. Chaque règle de détection de l'analyseur porte ces identifiants, l'export est donc prêt pour le rapport.
Un exemple réaliste de bout en bout
Pour voir tout cela sur des événements concrets, le déroulé d'un incident fictif suit un token de dashboard exposé jusqu'à cluster-admin et un crypto-mineur en 15 minutes d'événements d'audit. Les mêmes données sont derrière le bouton « Essayer un exemple » de la page de l'analyseur.
FAQ
Quelle est la première chose à faire quand un cluster Kubernetes est peut-être compromis ?
Préserver les preuves avant de toucher à quoi que ce soit : exporter les logs d'audit de l'API server sur toute la période, allonger leur rétention et sauvegarder les specs des workloads et bindings suspects. Supprimer d'abord un pod ou un binding détruit un contexte dont vous aurez besoin pour délimiter l'incident.
Les logs d'audit Kubernetes suffisent-ils pour enquêter sur une intrusion ?
Ils sont la trace principale de ce qui a été fait via l'API Kubernetes, mais ils ne voient pas les processus dans les conteneurs ni sur les nœuds. Complétez-les avec des alertes runtime, les logs des nœuds et des conteneurs, et les logs du plan de contrôle de votre fournisseur cloud.
Sur quelle période exporter les logs d'audit ?
Commencez quelques jours avant le premier événement suspect connu, et remontez plus loin dès que vous trouvez une trace antérieure de la même identité ou de la même IP source. L'accès initial précède souvent la partie bruyante d'une attaque.