Introduction
Le renforcement de la sécurité des événements Kubernetes avec des exemples pratiques doit aider les opérateurs à passer d'un problème observé à un résultat vérifié. Commencez par identifier la version installée, la topologie de déploiement, les prérequis et le composant exact inspecté.
Cet article se concentre sur la sécurité des événements Kubernetes pour les développeurs, les consultants DevOps et les équipes techniques de startups. Il relie le renforcement des événements Kubernetes, le contrôle d'accès aux événements Kubernetes, les secrets des événements Kubernetes et les permissions des événements Kubernetes aux commandes, à la sortie attendue, aux signaux d'échec et aux décisions de récupération qui correspondent à la technologie choisie.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire des versions et de l'environnement
Avant de modifier un paramètre de sécurité, établissez un inventaire des versions et de l'environnement. Cette section nomme le composant concerné (événement Kubernetes), la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Versions prises en charge et prérequis
- Kubernetes 1.25 ou version ultérieure (vérifiez avec
kubectl version --short) kubectlconfiguré avec un kubeconfig disposant d'un accès en lecture aux événements- Un espace de noms de test qui peut être recréé en toute sécurité
- Compréhension des RBAC, des groupes d'API et du cycle de vie des événements
Exécutez la commande en lecture seule suivante pour voir la version du serveur :
kubectl version --short
La sortie attendue devrait ressembler à :
Client Version: v1.28.2
Server Version: v1.28.2
Enregistrez la version, le nom du cluster et le contexte :
kubectl config current-context
Cette sortie (par exemple, arn:aws:eks:us-east-1:123456789012:cluster/prod-cluster) est essentielle pour la récupération et pour savoir quelles fonctionnalités d'API sont disponibles.
Observer la posture actuelle de sécurité des événements
Observez la visibilité actuelle des événements sans rien modifier. D'abord, listez les événements dans l'espace de noms par défaut :
kubectl get events -n default
Cela renvoie un tableau d'événements avec des colonnes comme LAST SEEN, TYPE, REASON, OBJECT et MESSAGE. Si vous voyez des événements de pods que vous ne reconnaissez pas, c'est un signal pour vérifier la source.
Pour voir tous les événements dans tous les espaces de noms avec des horodatages triables :
kubectl get events -A --sort-by=.metadata.creationTimestamp
C'est en lecture seule et aide à identifier un volume d'événements inhabituel ou des sources suspectes.
Petit changement de configuration vérifié
Un petit changement de renforcement consiste à restreindre l'accès par défaut aux événements pour les nouveaux comptes de service. Par défaut, les nouveaux espaces de noms ont un compte de service default sans permissions explicites. Cependant, de nombreux clusters utilisent des ClusterRoles agrégés qui peuvent accidentellement accorder la lecture des événements. La plus petite action réversible consiste à auditer quels rôles et rôles de cluster peuvent lire les événements.
D'abord, identifiez tous les rôles de cluster qui ont get, list ou watch sur les événements :
kubectl get clusterroles -o json | jq -r '.items[] | select(.rules[].resources[]? == "events") | .metadata.name' | sort -u
Exemple de sortie attendue :
system:events
custom-event-reader
Si vous trouvez un rôle de cluster personnalisé nommé custom-event-reader et que vous ne le reconnaissez pas, enquêtez sur sa liaison avant de changer quoi que ce soit :
kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name == "custom-event-reader") | .metadata.name'
Cela montre quels sujets (utilisateurs, groupes, comptes de service) sont liés. Le changement vérifié consiste à supprimer cette liaison uniquement si elle est confirmée comme inutilisée. Utilisez kubectl delete clusterrolebinding <nom> --dry-run=client -o yaml pour prévisualiser avant d'appliquer.
Commande de vérification pour le changement
Après tout changement, vérifiez que la lecture des événements n'est plus possible pour le principal concerné. Pour un compte de service nommé sa-test dans l'espace de noms default, utilisez kubectl auth can-i pour simuler :
kubectl auth can-i list events --as=system:serviceaccount:default:sa-test
La sortie attendue après renforcement est no. Avant le changement, elle aurait pu être yes. Cette commande est sûre et ne nécessite pas d'événements réels.
Chemin de configuration sécurisé
Pour la sécurité des événements Kubernetes, le chemin de configuration sécurisé définit une séquence minimale et réversible pour resserrer les contrôles d'accès sans casser les charges de travail. Ce chemin nomme le composant, les prérequis, l'observation, le plus petit changement justifié et la vérification.
Prérequis : audit RBAC
Assurez-vous d'avoir kubectl avec les permissions de visualiser les rôles et les liaisons, et jq pour le traitement JSON. Utilisez un espace de noms de test dédié pour éviter l'impact en production.
Créez un espace de noms sandbox :
kubectl create namespace event-sec-test
Vérifiez qu'il existe :
kubectl get namespace event-sec-test
La sortie devrait afficher le statut Active.
Observation : liaisons actuelles
Avant de modifier, listez toutes les liaisons de rôles dans l'espace de noms de test :
kubectl get rolebindings -n event-sec-test
S'il n'y en a pas, notez-le. S'il y a des liaisons, décrivez-les :
kubectl describe rolebinding <nom> -n event-sec-test
Recherchez tout sujet qui pourrait lire les événements, comme un compte de service ou un groupe.
Plus petit changement justifié : créer un rôle restrictif
Créez un rôle qui refuse explicitement la lecture des événements (utiliser un verbe personnalisé n'est pas possible ; vous pouvez seulement omettre les permissions). Pour garantir aucun accès aux événements, n'accordez pas get, list ou watch sur les événements. Créez plutôt un rôle qui accorde uniquement les permissions nécessaires pour une charge de travail, en excluant les événements.
Exemple role-minimal.yaml :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: event-sec-test
name: app-reader-no-events
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
Appliquez-le :
kubectl apply -f role-minimal.yaml
Puis créez une liaison de rôle pour un compte de service de test :
kubectl create serviceaccount sa-app -n event-sec-test
kubectl create rolebinding sa-app-binding -n event-sec-test --role=app-reader-no-events --serviceaccount=event-sec-test:sa-app
Vérifier l'accès
Vérifiez que le compte de service peut lister les pods (attendu : oui) :
kubectl auth can-i list pods --as=system:serviceaccount:event-sec-test:sa-app -n event-sec-test
Attendu : yes.
Vérifiez qu'il ne peut pas lister les événements (attendu : non) :
kubectl auth can-i list events --as=system:serviceaccount:event-sec-test:sa-app -n event-sec-test
Attendu : no.
Cela démontre un moindre privilège délimité.
Garder un rayon d'impact réduit
Testez toujours dans un espace de noms dédié. Utilisez kubectl port-forward pour tester les services localement avant de les exposer avec un équilibreur de charge. Par exemple :
kubectl port-forward svc/my-app 8080:80 -n event-sec-test
Puis testez avec curl http://localhost:8080 et observez les journaux :
kubectl logs deployment/my-app -n event-sec-test --tail=20
Si tout fonctionne, procédez à un déploiement contrôlé.
Vérification et diagnostics
Cette section fournit des commandes concrètes pour vérifier le renforcement de la sécurité des événements Kubernetes et diagnostiquer les problèmes. Chaque vérification est liée à un signal de succès ou d'échec.
Vérifier la visibilité des événements avec kubectl
En tant qu'utilisateur non privilégié (simulé via --as), tentez de visualiser les événements :
kubectl get events -n event-sec-test --as=system:serviceaccount:event-sec-test:sa-app
Sortie attendue sur un cluster renforcé :
Error from server (Forbidden): events is forbidden: User "system:serviceaccount:event-sec-test:sa-app" cannot list resource "events" in API group "" in the namespace "event-sec-test"
Si vous voyez une liste d'événements à la place, le rôle ou la liaison accorde toujours l'accès.
Confirmer les détails du rôle
Décrivez le rôle pour confirmer l'absence de permissions sur les événements :
kubectl describe role app-reader-no-events -n event-sec-test
La sortie devrait afficher uniquement les pods et les services sous les règles. Il ne devrait pas y avoir de ligne avec events.
Diagnostiquer un flot d'événements
Si des événements sont générés rapidement, inspectez la source en utilisant kubectl get events --sort-by=.lastTimestamp :
kubectl get events -n default --sort-by=.lastTimestamp | tail -20
Identifiez les événements répétés d'un objet particulier. Utilisez kubectl describe sur cet objet pour voir les événements récents :
kubectl describe pod <nom-du-pod> -n default
Regardez la section Events en bas pour des avertissements répétés comme BackOff ou FailedScheduling.
Utiliser les journaux d'audit pour des diagnostics approfondis
Si votre cluster a l'audit activé, recherchez les appels d'API liés aux événements :
kubectl logs -n kube-system kube-apiserver | grep -i 'events' | tail -20
Cela peut montrer quels utilisateurs ou comptes de service accèdent aux événements. Recherchez les champs user.username et requestURI.
Vérifier l'accès aux secrets
Vérifiez si un compte de service peut lire les secrets (qui accompagnent souvent les messages d'événements avec des données sensibles) :
kubectl auth can-i get secrets --as=system:serviceaccount:event-sec-test:sa-app -n event-sec-test
Si la réponse est yes, c'est un problème de sécurité. Vous devriez restreindre l'accès aux secrets de manière similaire.
Modes de défaillance et récupération
Même avec une planification minutieuse, des échecs peuvent survenir. Cette section décrit les modes de défaillance courants dans le renforcement de la sécurité des événements Kubernetes et comment récupérer.
Mode de défaillance 1 : RBAC trop restrictif casse l'application
Supposons que vous supprimiez les permissions d'événements d'un compte de service, puis qu'une application qui dépend de la lecture des événements pour surveiller la santé cesse de fonctionner. Les journaux de l'application montrent :
Error: events is forbidden
Récupération : identifiez la permission exacte nécessaire (par exemple, list events dans un espace de noms spécifique) et créez un rôle délimité accordant uniquement cela. N'accordez pas la lecture des événements à l'échelle du cluster.
Créez role-events-read.yaml :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: event-sec-test
name: events-reader
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list"]
Appliquez et liez uniquement à ce compte de service :
kubectl apply -f role-events-read.yaml
kubectl create rolebinding events-reader-binding -n event-sec-test --role=events-reader --serviceaccount=event-sec-test:sa-app
Vérifiez :
kubectl auth can-i list events --as=system:serviceaccount:event-sec-test:sa-app -n event-sec-test
Maintenant, la réponse devrait être yes, mais uniquement dans cet espace de noms.
Mode de défaillance 2 : Suppression accidentelle d'une liaison ou d'un rôle
Si vous supprimez la mauvaise liaison de rôle, les applications peuvent perdre toutes les permissions, provoquant des interruptions de service. Restaurez immédiatement à partir de la sauvegarde de configuration. Si vous utilisez GitOps, réappliquez le manifeste :
kubectl apply -f original-rolebinding.yaml
S'il n'y a pas de sauvegarde, recréez manuellement en listant l'ancienne liaison à partir des journaux d'audit ou de kubectl get rolebindings si elle n'a pas été entièrement supprimée. À l'avenir, utilisez kubectl get rolebinding -o yaml avant de supprimer.
Mode de défaillance 3 : Les données d'événements contiennent des secrets en raison d'erreurs de spécification de pod
Parfois, une spécification de pod incorpore des secrets comme variables d'environnement, et lorsque le pod échoue, les événements Kubernetes incluent le message d'erreur révélant le secret. Par exemple, un pod essayant de monter un secret inexistant peut générer un événement comme :
MountVolume.SetUp failed for volume "secret-volume" : secret "mysecret" not found
Cela révèle le nom du secret. Pour récupérer, supprimez d'abord la référence au secret ou créez le secret manquant. Ensuite, censurez ou supprimez l'événement :
kubectl delete events --all -n default
Remarque : la suppression des événements n'est possible que si vous avez la permission ; les événements sont automatiquement supprimés après une heure par défaut.
Évitez cela en n'intégrant pas de secrets directement dans les spécifications de pod, et en utilisant les secrets Kubernetes montés comme volumes ou accédés via l'API.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle avant, pendant et après le renforcement de la sécurité des événements Kubernetes. Remplacez les espaces réservés par vos informations spécifiques.
Liste de contrôle pré-changement (lecture seule)
- [ ] Vérifiez la version de Kubernetes :
kubectl version --short(attendu : 1.25+) - [ ] Enregistrez le contexte actuel :
kubectl config current-context - [ ] Listez tous les rôles et liaisons liés aux événements :
kubectl get roles,rolebindings,clusterroles,clusterrolebindings -A | grep -i event - [ ] Sauvegardez la configuration RBAC actuelle :
kubectl get roles,rolebindings,clusterroles,clusterrolebindings -A -o yaml > rbac-backup-$(date +%Y%m%d).yaml - [ ] Identifiez l'espace de noms de test et le compte de service à utiliser
- [ ] Documentez le plan de restauration
Liste de contrôle du changement (plus petit changement justifié)
- [ ] Appliquez le nouveau rôle avec le moindre privilège, par exemple,
kubectl apply -f role-minimal.yaml - [ ] Liez le rôle au compte de service de test :
kubectl create rolebinding ... - [ ] Protégez les secrets : assurez-vous qu'aucun nouveau secret n'est exposé via les événements (vérifiez
kubectl get eventspour les chaînes sensibles) - [ ] Limitez les permissions : supprimez la lecture des événements de tout rôle large si ce n'est pas nécessaire
Liste de contrôle de vérification (post-changement)
- [ ] Exécutez
kubectl auth can-i list events --as=system:serviceaccount:test:sa-test -n test(attendu :no) - [ ] Exécutez
kubectl get events --as=system:serviceaccount:test:sa-test -n test(attendu : Forbidden) - [ ] Vérifiez les journaux d'application pour les erreurs de permission :
kubectl logs deployment/app -n test --tail=20 - [ ] Assurez-vous qu'aucun flot d'événements inattendu ne se produit :
kubectl get events -n test --sort-by=.lastTimestamp | tail -10 - [ ] Testez la fonctionnalité de la charge de travail avec
kubectl port-forwardetcurl
Liste de contrôle de récupération (si quelque chose casse)
- [ ] Identifiez le principal cassé à partir des journaux ou des événements d'audit
- [ ] Restaurez le RBAC d'origine à partir de la sauvegarde :
kubectl apply -f rbac-backup-YYYYMMDD.yaml - [ ] Vérifiez que l'accès est restauré :
kubectl auth can-i list events --as=system:serviceaccount:test:sa-test -n test - [ ] Documentez l'incident et ajustez les rôles de manière minimale
Conclusion
Le renforcement de la sécurité des événements Kubernetes avec des exemples pratiques n'est utile que lorsque chaque recommandation est limitée à une version, observable et réversible lorsque la technologie le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure opérationnelle.
Comme prochaine étape, choisissez une vérification à faible risque pour la sécurité des événements Kubernetes, enregistrez l'état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et passez en revue les dépendances telles que Kubectl, Node et Pod.
Un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.