📍 Article principal du cluster : CKS Certified Kubernetes Security Specialist — guide complet 2026
Ce tutoriel fait partie du cluster certification CKS. Pour la vue d’ensemble, lisez d’abord le pilier.
Introduction
Le domaine 6 « Monitoring, Logging and Runtime Security » pèse 20 % de l’examen CKS. Il teste votre capacité à détecter et bloquer en temps réel les comportements malveillants au runtime — un shell ouvert dans un conteneur, un accès à /etc/shadow, un mount privilégié, une élévation de privilèges. L’outil incontournable est Falco, un agent eBPF/kernel-module qui inspecte les syscalls et matche contre des règles déclaratives. Ce tutoriel installe Falco sur un cluster kind 1.34, écrit des règles custom, intègre les alertes avec Falco Sidekick, et analyse les audit logs Kubernetes pour la corrélation post-mortem.
Prérequis
- Cluster kind 1.34 fonctionnel
- Tutoriels CKS précédents terminés (kube-bench, OPA, Trivy)
- 40 minutes
Étape 1 — Installer Falco via Helm
Falco s’installe le plus simplement via Helm. Le chart officiel configure le DaemonSet, les RoleBindings, et la configuration de base. Le mode driver dépend du kernel — pour kind sur Ubuntu 24.04, modern_ebpf fonctionne directement sans modules kernel.
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
bash get_helm.sh
helm version
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
kubectl create namespace falco
helm install falco falcosecurity/falco \
--namespace falco \
--set driver.kind=modern_ebpf \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true
sleep 30
kubectl get pods -n falco
kubectl logs -n falco -l app.kubernetes.io/name=falco | head -20
Les Pods Falco doivent passer en Running. Les logs initiaux affichent « Falco initialized with configuration » et listent les règles chargées par défaut (environ 50 règles preset). Ce sont ces règles qui détectent les comportements connus : shell dans un conteneur, package management dans un conteneur, accès aux secrets sensibles.
Étape 2 — Provoquer une détection avec un shell dans un conteneur
Test fondamental : ouvrir un shell interactif dans un Pod. Falco doit détecter immédiatement et logguer une alerte.
kubectl run target --image=nginx:1.27
sleep 5
kubectl exec -it target -- /bin/bash &
EXEC_PID=$!
sleep 3
# Voir l'alerte Falco
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=20 | grep -i shell
kill $EXEC_PID 2>/dev/null
Vous devez voir une ligne « Notice A shell was spawned in a container with an attached terminal » avec les détails du Pod, image, et utilisateur. Cette détection est la base de toutes les investigations sécurité Kubernetes en production.
Étape 3 — Écrire une règle Falco custom
Les règles built-in couvrent les cas généraux. Pour des détections business, on écrit des règles custom — testées au domaine 6 du syllabus.
cat > /tmp/falco-custom-rules.yaml <<'EOF'
customRules:
custom-rules.yaml: |-
- rule: Detect Curl/Wget in Container
desc: An HTTP download tool was spawned in a container, possible reconnaissance
condition: spawned_process and container and (proc.name in (curl, wget))
output: HTTP tool spawned in container (user=%user.name container_id=%container.id image=%container.image.repository proc=%proc.name cmd=%proc.cmdline)
priority: WARNING
tags: [container, network]
- rule: Detect Read Sensitive File
desc: An attempt to read a sensitive file was made
condition: open_read and container and fd.name in (/etc/shadow, /etc/sudoers, /root/.ssh/authorized_keys)
output: Sensitive file read (user=%user.name container_id=%container.id file=%fd.name)
priority: CRITICAL
tags: [filesystem, sensitive]
- rule: Detect Crypto Mining Pool Connection
desc: Connection to a known crypto mining pool detected
condition: outbound and (fd.sip.name endswith ".cryptopool.com" or fd.sip.name endswith ".pool.minexmr.com")
output: Crypto mining detected (container=%container.id pool=%fd.sip.name)
priority: CRITICAL
tags: [crypto, network]
EOF
helm upgrade falco falcosecurity/falco \
--namespace falco \
--set driver.kind=modern_ebpf \
--set falcosidekick.enabled=true \
-f /tmp/falco-custom-rules.yaml
sleep 30
Les règles custom sont rechargées à chaud par Falco. Testez : `kubectl exec -it target — curl -s ifconfig.io` doit déclencher l’alerte « HTTP tool spawned in container ».
Étape 4 — Configurer Falco Sidekick pour Slack/Mattermost
Falco Sidekick reçoit les alertes Falco et les forwarde vers des destinations diverses : Slack, Mattermost, Mail, Loki, S3, Webhook custom. Configuration simple via Helm values.
cat > /tmp/sidekick-values.yaml <<'EOF'
falcosidekick:
enabled: true
config:
slack:
webhookurl: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
minimumpriority: warning
mattermost:
webhookurl: ""
smtp:
hostport: "smtp.example.com:587"
from: "falco@example.com"
to: "soc@example.com"
EOF
# helm upgrade en réutilisant les valeurs précédentes
echo "Sidekick configuré — les alertes WARNING et CRITICAL partent vers Slack"
Une alerte reçue dans Slack ressemble à : `🚨 [WARNING] Notice A shell was spawned in container nginx (user=root)`. C’est ce que les SOC modernes utilisent pour la première ligne de réponse à incident.
Étape 5 — Audit logs Kubernetes pour corrélation
Falco détecte au niveau syscall ; les audit logs Kubernetes tracent au niveau API. Les deux sont complémentaires : Falco voit « shell ouvert dans Pod X », audit log voit « kubectl exec sur Pod X par user Y ». Corrélation = qui a ouvert le shell.
tail -50 /tmp/audit/audit.log 2>/dev/null | grep -E "exec|attach" | head -3
Le JSONL audit log montre l’utilisateur, le verbe (exec), la ressource (pod/target), le timestamp. Croisé avec l’alerte Falco au même timestamp, on identifie l’auteur. C’est un workflow examen courant.
Étape 6 — Détection runtime — fichier sensible
Test de la règle custom « Detect Read Sensitive File ». On lance un Pod et on tente de lire /etc/shadow.
kubectl run sensitive-test --image=busybox:1.37 --command -- sleep 3600
sleep 5
kubectl exec sensitive-test -- cat /etc/shadow 2>/dev/null || echo "Lecture refusée"
# Voir l'alerte Falco
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=10 | grep -i sensitive
Falco détecte la lecture de /etc/shadow et logge une alerte CRITICAL. Même si le fichier est minimal dans busybox, le syscall open_read sur ce path est intercepté et matché contre la règle.
Étape 7 — ImmutableConfigMap et conteneurs immuables
Le domaine 6c teste « ensure container immutability at runtime ». Pratiquement : ConfigMap immutable + readOnlyRootFilesystem + capabilities drop.
cat > /tmp/immutable-cm.yaml <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-frozen
data:
app.conf: |
log_level=info
api_url=https://api.example.com
immutable: true
EOF
kubectl apply -f /tmp/immutable-cm.yaml
# Tentative de modification — doit échouer
kubectl edit configmap app-config-frozen
# Ou : kubectl patch cm app-config-frozen -p '{"data":{"app.conf":"changed"}}'
# Erreur "field is immutable"
Le flag `immutable: true` sur un ConfigMap empêche toute modification — il faut le supprimer et le recréer. Cette propriété protège contre les modifications accidentelles ou malveillantes en production.
Étape 8 — Pod immuable end-to-end
Combinaison de tous les principes pour un Pod immutable au runtime.
cat > /tmp/pod-immutable.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: immutable-app
spec:
containers:
- name: app
image: nginx:1.27-alpine
ports:
- containerPort: 80
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/nginx
- name: run
mountPath: /var/run
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
runAsNonRoot: false
capabilities:
drop: ["ALL"]
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
- name: run
emptyDir: {}
EOF
kubectl apply -f /tmp/pod-immutable.yaml
kubectl get pod immutable-app
kubectl exec immutable-app -- touch /test-write 2>&1 || echo "Filesystem read-only OK"
Le `touch /test-write` échoue car le filesystem racine est en read-only. Les volumes emptyDir montés en /tmp, /var/cache/nginx, /var/run permettent à nginx de démarrer (il a besoin d’écrire son pid file et son cache). C’est exactement le pattern « container immuable » testé en domaine 6c.
Comprendre la différence eBPF, kernel module et userspace pour Falco
Falco peut tourner avec trois drivers d’inspection des syscalls. kernel module (legacy) — un module noyau classique, performant mais demande des privilèges et un kernel compatible. eBPF probes (CO-RE) — programmes eBPF chargés dans le noyau, fonctionne sur kernel 5.8+. modern_ebpf — implémentation moderne basée sur les hooks eBPF Tracepoints, défaut recommandé en 2026 pour kernel 5.13+.
Pour kind sur Ubuntu 24.04, modern_ebpf fonctionne immédiatement. Pour des nœuds production avec kernel plus ancien, le fallback est ebpf classique. Le kernel module reste utilisé dans les environnements très contraints. Pour CKS v1.34, attendez-vous à des questions de configuration sur ces trois modes.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Falco refuse de démarrer | Kernel incompatible avec modern_ebpf | Basculer driver.kind=ebpf ou kernel-module et relancer Helm |
| Aucune alerte malgré shell ouvert | Règle « Terminal shell » désactivée | Vérifier `kubectl exec falco — falco –list` qui liste les règles actives |
| Sidekick reçoit les alertes mais ne forwarde pas | Webhook URL invalide | Tester manuellement le webhook avec curl avant configuration Falco |
| readOnlyRootFilesystem casse l’application | App tente d’écrire en /var ou /tmp | Identifier les chemins via strace puis ajouter emptyDir mounts |
| Audit logs vides | Policy audit non configurée | Vérifier le manifest kube-apiserver pour `–audit-policy-file` |
Adaptation au contexte ouest-africain
Pour les SOC ouest-africains naissants à Dakar (CIS Sénégal, ANSCT) ou Abidjan (privé Suricate, Wave Tech), Falco est l’outil d’observabilité runtime de référence — gratuit, open-source, et avec une communauté CNCF active. Les startups qui montent leurs premiers clusters production peuvent intégrer Falco + Sidekick + Slack en moins d’une journée. Pour la corrélation avancée, l’intégration Falco → Loki → Grafana sur un cluster k3s Hostinger Cloud Startup à 9,99 USD/mois donne un SIEM léger fonctionnel sans abonnement Datadog ou Splunk hors de portée budget.
Tutoriels frères
Pour aller plus loin
- 🔝 Retour au pilier : CKS — guide complet 2026
- Falco documentation : falco.org/docs
- Bibliothèque de règles communautaires : github.com/falcosecurity/rules
- Audit logging Kubernetes : kubernetes.io/docs/tasks/debug/debug-cluster/audit
FAQ
Falco a-t-il un coût en performance ?
Avec modern_ebpf, l’overhead est typiquement < 5 % CPU sur les nœuds workers. Acceptable pour 99 % des cas d’usage production.
Peut-on bloquer une action plutôt que juste la logger ?
Falco lui-même est un détecteur. Pour bloquer, intégrez Falco Talon (réponse automatisée) ou Tetragon (Cilium) qui peut tuer un processus matché.
Mots-clés secondaires : falco runtime security, falcosidekick slack, ebpf kubernetes, audit logs k8s, container immutability, readonly root filesystem, immutable configmap