Bank 8 – Études de cas (Partie 2 : Configuration / Sécurité)¶
Instructions
Analysez la mise en situation et répondez aux consignes.
Cliquez sur « Corrigé & Barème » pour comparer.
Total : 5 cas (2 intermédiaires · 3 difficiles)
Niveau Intermédiaire¶
Cas 2.3 : Gestion des clés d'API et rechargement dynamique sans arrêt¶
Mise en situation :
L'application gateway-service consomme une clé d'API tierce stockée dans un Secret. La clé d'API doit être renouvelée régulièrement. L'équipe souhaite que le renouvellement de la clé dans le cluster soit pris en compte par l'application sans devoir redémarrer le pod.
Consignes :
- Expliquez pourquoi l'injection du Secret sous forme de variable d'environnement (
env) ne répond pas au besoin de rechargement dynamique. - Détaillez la méthode d'injection permettant la mise à jour à chaud du fichier dans le conteneur.
- Décrivez l'architecture applicative nécessaire (ex. pattern de watcher) pour que l'application détecte le changement sur le système de fichiers.
??? success "Corrigé & Barème" 1. Incapacité des variables d'env (1.5 pt) : Les variables d'environnement sont injectées lors de l'initialisation du processus du conteneur. Toute modification ultérieure du Secret dans l'API Kubernetes ne mettra jamais à jour le processus en cours d'exécution ; un redémarrage complet du pod est requis. 2. Méthode par montage de Volume (2 pts) : Il faut monter le Secret sous forme de volume (volumes de type secret et volumeMounts). Kubernetes met automatiquement à jour les fichiers symboliques dans le répertoire monté de façon asynchrone lorsque le Secret est modifié dans l'API. 3. Architecture applicative (1.5 pt) : L'application doit implémenter un mécanisme de surveillance de fichier (ex. inotify en Linux, ou une boucle de lecture périodique de l'horodatage du fichier) pour recharger la clé en mémoire dès qu'elle détecte une modification sur le disque monté.
Cas 2.4 : Contrôle des accès développeurs via un Namespace dédié et un Role RBAC¶
Mise en situation :
Une nouvelle équipe de prestataires rejoint le projet. Vous devez leur donner un accès complet de consultation et de gestion des Pods, Deployments et Services dans l'espace de noms staging, mais leur interdire strictement toute action dans l'espace production ainsi que la lecture des Secrets de staging.
Consignes :
- Rédigez le manifeste YAML de l'objet
Roleà créer dans le namespacestaging. - Rédigez le manifeste
RoleBindingassociant ce rôle au groupe d'utilisateursprestataires-dev.
??? success "Corrigé & Barème" - Manifeste du Role (3 pts) :
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: dev-staging-role
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "services"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
(Note : Vérifier l'absence explicite de la ressource "secrets"). - Manifeste du RoleBinding (2 pts) :
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-dev-staging
namespace: staging
subjects:
- kind: Group
name: prestataires-dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-staging-role
apiGroup: rbac.authorization.k8s.io
Niveau Difficile¶
Cas 2.5 : Audit d'escalade de privilèges via un pod débuggeur¶
Mise en situation :
Lors d'un contrôle de sécurité automatisé, le système d'alerte signale la création d'un Pod suspect nommé cluster-debugger dans le namespace default. L'analyse de son manifeste YAML révèle la configuration suivante :
spec:
hostNetwork: true
hostPID: true
containers:
- name: shell
image: alpine
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: host-volume
volumes:
- name: host-volume
hostPath:
path: /
Consignes :
- Analysez les 4 failles critiques présentes dans ce manifeste et expliquez comment un attaquant peut les exploiter pour prendre le contrôle total du serveur hôte k3s.
- Indiquez quel outil ou politique native de sécurité Kubernetes (Pod Security Standards / Admission Controllers) permet de bloquer préventivement le déploiement de ce type de pod sur le cluster.
??? success "Corrigé & Barème" - Analyse des 4 failles d'escalade (4 pts) : - hostNetwork: true : Le pod partage la pile réseau de l'hôte, lui permettant d'écouter le trafic local, d'accéder aux interfaces Loopback de la machine et de contourner les règles réseau isolées. - hostPID: true : Le pod voit tous les processus s'exécutant sur l'hôte physique (y compris k3s, kubelet, etc.) et peut leur envoyer des signaux ou inspecter leur mémoire. - privileged: true : Le conteneur désactive l'isolation du noyau Linux, contourne AppArmor/Seccomp et obtient un accès complet à tous les périphériques (/dev) du nœud. - hostPath: / monté sur /host : Accès direct en lecture/écriture à l'intégralité du système de fichiers du serveur hôte, permettant d'altérer les binaires, d'ajouter une clé SSH dans /root/.ssh/authorized_keys ou d'extraire les certificats du cluster. - Moyen de prévention (1 pt) : Activer les Pod Security Standards (PSS) au niveau du namespace en appliquant le profil baseline ou restricted via des labels d'admission (ex. pod-security.kubernetes.io/enforce: restricted), bloquant ainsi les conteneurs privilégiés et les partages d'espaces de noms hôte.
Cas 2.6 : Attaque par fuite de jeton de ServiceAccount et sécurisation Bound Service Account Tokens¶
Mise en situation :
Une vulnérabilité de type Path Traversal sur une application web a permis à un attaquant distant de lire le fichier /var/run/secrets/kubernetes.io/serviceaccount/token présent dans le conteneur. Utilisant ce jeton, l'attaquant a pu émettre des requêtes directes vers l'API Server depuis l'extérieur du cluster.
Consignes :
- Pourquoi ce jeton était-il présent dans le conteneur par défaut et quelle propriété du jeton a permis son utilisation sans limite de durée ?
- Quelles sont les 2 étapes immédiates pour bloquer l'attaque sur l'API Server ?
- Rédigez l'instruction à ajouter au manifeste du Pod pour désactiver l'injection automatique du jeton de compte de service pour les applications n'interagissant pas avec l'API.
??? success "Corrigé & Barème" - Cause de la fuite et pérennité (1.5 pt) : Kubernetes monte par défaut le jeton du ServiceAccount de l'espace de noms dans chaque pod (automountServiceAccountToken: true). Historiquement, ces jetons sous forme de Secrets étaient permanents et n'avaient pas de date d'expiration. - Actions de blocage immédiat (1.5 pt) : - Supprimer ou réinvalider le ServiceAccount compromis (ou supprimer/régénérer la clé du secret associé). - Révoquer les permissions RBAC liées à ce compte ou supprimer les RoleBinding associés. - Instruction de désactivation (2 pts) : Ajouter la ligne automountServiceAccountToken: false au niveau du spec du Pod :
yaml
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
automountServiceAccountToken: false
containers:
- name: web
image: nginx
Cas 2.7 : Mettre en œuvre une politique Zero-Trust Network Policy avec Ingress et Egress¶
Mise en situation :
Vous devez sécuriser l'espace de noms billing selon une approche Zero-Trust. L'application payment-processor située dans ce namespace doit répondre uniquement aux requêtes arrivant de frontend (port 443) et ne doit pouvoir initier de connexions sortantes que vers une base de données MySQL externe résidant sur l'IP fixe 192.168.10.50/32 (port 3306). Tout autre flux (Ingress et Egress) doit être strictement bloqué.
Consignes :
- Expliquez le concept de la règle "Default Deny All" (Ingress et Egress) dans une NetworkPolicy.
- Écrivez le manifeste YAML complet de la NetworkPolicy répondant scrupuleusement à l'ensemble du cahier des charges.
??? success "Corrigé & Barème" - Concept Default Deny Ingress/Egress (1.5 pt) : En déclarant policyTypes: [Ingress, Egress] avec un podSelector sélectionnant les pods du namespace, tout trafic n'étant pas explicitement autorisé dans les sections ingress et egress est immédiatement bloqué par le plugin CNI. - Manifeste NetworkPolicy YAML (3.5 pts) :
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payment-zero-trust
namespace: billing
spec:
podSelector:
matchLabels:
app: payment-processor
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 443
egress:
- to:
- ipBlock:
cidr: 192.168.10.50/32
ports:
- protocol: TCP
port: 3306