Introduction : pourquoi la sécurité runtime est devenue incontournable
Les conteneurs Linux ont complètement changé la donne en matière de déploiement et d'exploitation des applications. Docker, Kubernetes, containerd — on les retrouve partout aujourd'hui. Mais soyons honnêtes : cette révolution s'accompagne d'un problème de taille. Les mécanismes de sécurité classiques — pare-feu périmétriques, antivirus, IDS réseau — ne sont tout simplement pas adaptés au monde des conteneurs.
Les conteneurs sont éphémères. Ils partagent le noyau de l'hôte. Ils communiquent via des réseaux virtuels complexes. Un conteneur compromis peut tenter d'escalader ses privilèges, récupérer les secrets du cluster, ou pire, s'échapper vers l'hôte sous-jacent.
Et les menaces ne font que se sophistiquer. Le framework malveillant VoidLink, découvert fin 2025 par les chercheurs de Check Point Research, en est un parfait exemple. Ce malware détecte automatiquement s'il tourne dans un conteneur Docker ou un pod Kubernetes, puis déploie des modules d'évasion, d'extraction de secrets et de mouvement latéral adaptés au cloud identifié (AWS, GCP, Azure). Le comble ? Il utilise eBPF pour sa furtivité — exactement la même technologie qu'on utilise pour se défendre. Ça donne à réfléchir.
C'est là qu'entre en jeu la sécurité runtime basée sur eBPF (extended Berkeley Packet Filter). Cette technologie permet d'instrumenter le noyau Linux en temps réel, sans toucher au code du kernel ni installer de modules noyau, pour observer chaque appel système, chaque connexion réseau, chaque accès fichier effectué par un conteneur. Des outils comme Falco (projet CNCF graduated) et Tetragon (Cilium/Isovalent) exploitent eBPF pour détecter et bloquer les comportements malveillants au moment même où ils se produisent.
Dans ce guide, on va couvrir pas mal de terrain : les fondamentaux d'eBPF pour la sécurité, le déploiement de Falco et Tetragon, l'écriture de règles de détection personnalisées, la réponse automatisée aux incidents et l'intégration dans un pipeline DevSecOps. Chaque section contient des exemples concrets, prêts à déployer. Alors, c'est parti.
eBPF : le socle technologique de la sécurité runtime moderne
Comment eBPF révolutionne la sécurité du noyau Linux
Pour comprendre la puissance de Falco et Tetragon, il faut d'abord saisir ce qu'est eBPF. Historiquement, instrumenter le noyau Linux pour la sécurité, c'était soit compiler des modules noyau (risqué et fragile), soit patcher le kernel lui-même. Pas idéal.
eBPF change fondamentalement la donne. Il permet d'exécuter des programmes sandboxés directement dans l'espace noyau, avec une vérification statique qui garantit qu'ils ne peuvent ni crasher le système, ni accéder à la mémoire de manière arbitraire.
Concrètement, les programmes eBPF peuvent se rattacher à des centaines de points d'ancrage (hooks) dans le noyau :
- Tracepoints : points d'instrumentation statiques dans le noyau (appels système, gestion mémoire, ordonnancement)
- Kprobes/Kretprobes : instrumentation dynamique de n'importe quelle fonction du noyau
- LSM hooks : points d'accroche du Linux Security Module pour l'application de politiques de sécurité
- TC hooks : filtrage et modification du trafic réseau au niveau du contrôleur de trafic
- XDP : traitement réseau ultra-rapide, avant même la pile réseau du noyau
Pour la sécurité des conteneurs, les tracepoints sur les appels système sont particulièrement précieux. Chaque action d'un conteneur — exécuter un processus, ouvrir un fichier, établir une connexion — passe obligatoirement par un appel système. En surveillant ces appels avec eBPF, on obtient une visibilité complète sur le comportement de chaque conteneur, avec un overhead typiquement entre 1 et 5 % de CPU. C'est remarquablement léger pour ce niveau de visibilité.
eBPF vs Seccomp vs AppArmor : complémentarité, pas remplacement
Un point important : eBPF ne remplace pas les mécanismes de sécurité existants — il les complète. Voici comment ces technologies se positionnent :
- Seccomp-BPF : filtre les appels système autorisés pour un conteneur. Excellent pour réduire la surface d'attaque, mais limité — il ne peut pas inspecter les arguments des appels système ni comprendre le contexte (quel fichier est ouvert, quelle IP est contactée)
- AppArmor / SELinux : contrôle d'accès obligatoire (MAC) définissant quels fichiers, réseaux et capacités sont accessibles. Puissant mais statique : les politiques sont définies avant l'exécution et ne s'adaptent pas aux comportements dynamiques
- eBPF runtime security : observation et action en temps réel avec un contexte riche — processus parent, arborescence complète, métadonnées Kubernetes, contenu des arguments. C'est la détection comportementale que les mécanismes précédents ne peuvent tout simplement pas offrir
La meilleure stratégie ? Une défense en profondeur combinant les trois : Seccomp pour limiter la surface d'attaque, AppArmor/SELinux pour le contrôle d'accès, et eBPF pour la détection et la réponse runtime.
Falco : la détection d'intrusion runtime de référence
Architecture et fonctionnement
Falco est le projet de sécurité runtime le plus mature de l'écosystème CNCF. Passé au statut « graduated » en 2024, il est utilisé en production par des milliers d'organisations. Son architecture repose sur trois composants principaux :
- Le driver eBPF (ou module noyau) : capture les événements du noyau — appels système, événements réseau, accès fichiers
- Le moteur de règles : évalue les événements en temps réel contre un ensemble de règles YAML définissant les comportements suspects
- Les sorties : transmet les alertes vers syslog, stdout, webhooks, gRPC, ou des systèmes SIEM via des plugins
Depuis la version 0.42.0 (octobre 2025), Falco intègre une fonctionnalité de capture (capture recording) qui permet d'enregistrer les événements au format .scap pour analyse forensique ultérieure. La version 0.43.0 stabilise cette fonctionnalité et introduit l'initiative « drop-enter » qui améliore significativement les performances en filtrant les événements non pertinents plus tôt dans le pipeline. Un vrai gain, surtout sur les clusters à forte charge.
Installation de Falco sur un hôte Linux
Voici comment installer Falco avec le driver eBPF moderne sur Debian/Ubuntu :
# Ajouter le dépôt Falco
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] \
https://download.falco.org/packages/deb stable main" | \
sudo tee /etc/apt/sources.list.d/falcosecurity.list
sudo apt-get update
sudo apt-get install -y falco
# Vérifier que le driver eBPF est chargé
sudo falco --version
sudo systemctl status falco
Et pour RHEL/CentOS/Fedora :
# Ajouter le dépôt RPM
sudo rpm --import https://falco.org/repo/falcosecurity-packages.asc
cat << EOF | sudo tee /etc/yum.repos.d/falcosecurity.repo
[falcosecurity]
name=Falco Security Repository
baseurl=https://download.falco.org/packages/rpm/
enabled=1
gpgcheck=1
gpgkey=https://falco.org/repo/falcosecurity-packages.asc
EOF
sudo dnf install -y falco
sudo systemctl enable --now falco
Déploiement de Falco sur Kubernetes avec Helm
Le déploiement le plus courant passe par Helm pour installer Falco comme DaemonSet sur chaque nœud du cluster :
# Ajouter le chart Helm de Falco
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
# Installation avec le driver eBPF moderne
helm install falco falcosecurity/falco \
--namespace falco \
--create-namespace \
--set driver.kind=modern_ebpf \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true \
--set collectors.kubernetes.enabled=true
# Vérifier le déploiement
kubectl -n falco get pods
kubectl -n falco logs -l app.kubernetes.io/name=falco --tail=20
L'option falcosidekick est vraiment essentielle ici : c'est le composant qui route les alertes Falco vers vos systèmes de notification — Slack, PagerDuty, Elasticsearch, Kafka, et plus de 60 autres destinations. Sans lui, vous auriez des alertes mais personne pour les voir.
Comprendre et écrire des règles Falco
Les règles Falco sont écrites en YAML et suivent une structure déclarative. Chaque règle définit une condition à surveiller et une sortie à produire quand la condition est remplie :
# Structure d'une règle Falco
- rule: Nom de la règle
desc: Description détaillée du comportement détecté
condition: >
expression booléenne utilisant les champs des événements
output: >
Message d'alerte avec des champs dynamiques
priority: WARNING # EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG
tags: [conteneur, réseau, fichier]
enabled: true
Maintenant, passons aux choses sérieuses. Voici des règles personnalisées adaptées aux menaces actuelles :
# /etc/falco/rules.d/custom-container-rules.yaml
# Détection d'exécution de shell dans un conteneur
- rule: Shell exécuté dans un conteneur
desc: >
Détecte l'exécution d'un shell interactif dans un conteneur.
Ceci peut indiquer une tentative d'exploration post-exploitation.
condition: >
spawned_process and
container and
proc.name in (bash, sh, zsh, dash, ksh, csh, fish) and
proc.tty != 0
output: >
Shell interactif lancé dans un conteneur
(utilisateur=%user.name conteneur=%container.name
image=%container.image.repository commande=%proc.cmdline
pod=%k8s.pod.name namespace=%k8s.ns.name)
priority: WARNING
tags: [conteneur, shell, mitre_execution]
# Détection de lecture de secrets Kubernetes
- rule: Accès suspect aux secrets montés
desc: >
Détecte la lecture de fichiers dans les répertoires de secrets
Kubernetes montés dans un conteneur.
condition: >
open_read and
container and
fd.name startswith /var/run/secrets/kubernetes.io/ and
not proc.name in (kubelet, kube-proxy, coredns)
output: >
Lecture de secret Kubernetes détectée
(fichier=%fd.name processus=%proc.name image=%container.image.repository
pod=%k8s.pod.name namespace=%k8s.ns.name)
priority: CRITICAL
tags: [conteneur, kubernetes, secrets, mitre_credential_access]
# Détection de connexion réseau sortante inhabituelle
- rule: Connexion sortante suspecte depuis un conteneur
desc: >
Détecte les connexions réseau sortantes vers des ports
non standard depuis un conteneur de production.
condition: >
outbound and
container and
fd.sport in (4444, 5555, 8888, 9001, 1337, 31337) and
not k8s.ns.name in (monitoring, logging)
output: >
Connexion sortante suspecte depuis un conteneur
(ip_dest=%fd.sip port=%fd.sport processus=%proc.name
image=%container.image.repository pod=%k8s.pod.name)
priority: CRITICAL
tags: [conteneur, réseau, mitre_command_and_control]
# Détection de tentative d'évasion de conteneur
- rule: Tentative évasion via montage de volumes hôte
desc: >
Détecte les tentatives d'accès au système de fichiers de
l'hôte depuis un conteneur via des chemins sensibles.
condition: >
open_read and
container and
(fd.name startswith /proc/1/ or
fd.name startswith /host/ or
fd.name = /etc/shadow or
fd.name startswith /var/run/docker.sock)
output: >
Tentative d'évasion de conteneur détectée
(fichier=%fd.name processus=%proc.cmdline
conteneur=%container.name image=%container.image.repository
pod=%k8s.pod.name)
priority: EMERGENCY
tags: [conteneur, évasion, mitre_privilege_escalation]
# Détection d'outils de reconnaissance réseau
- rule: Outil de scan réseau dans un conteneur
desc: >
Détecte l'exécution d'outils de scan et de reconnaissance
réseau dans un conteneur.
condition: >
spawned_process and
container and
proc.name in (nmap, masscan, zmap, ncat, netcat, nc, socat, curl, wget) and
not k8s.ns.name in (security-scanning, pentest)
output: >
Outil de reconnaissance réseau exécuté dans un conteneur
(outil=%proc.name arguments=%proc.cmdline
conteneur=%container.name pod=%k8s.pod.name
namespace=%k8s.ns.name)
priority: WARNING
tags: [conteneur, réseau, reconnaissance, mitre_discovery]
Tester et valider les règles
Avant de balancer vos règles en production (ne faites jamais ça à l'aveugle), testez-les rigoureusement :
# Valider la syntaxe des règles
sudo falco --validate /etc/falco/rules.d/custom-container-rules.yaml
# Exécuter Falco en mode dry-run avec vos règles
sudo falco -r /etc/falco/rules.d/custom-container-rules.yaml --dry-run
# Tester en déclenchant manuellement une alerte
# Dans un terminal, lancez un conteneur et exécutez un shell :
docker run -it --rm alpine sh
# Dans un autre terminal, observez les alertes Falco :
sudo falco -r /etc/falco/rules.d/custom-container-rules.yaml \
-o json_output=true | jq '.'
Tetragon : observation et blocage au niveau du noyau
Pourquoi Tetragon en plus de Falco ?
Si Falco excelle dans la détection flexible basée sur des règles, Tetragon amène quelque chose de fondamentalement différent : l'application de politiques directement dans le noyau. Là où Falco détecte et alerte, Tetragon peut aussi bloquer — envoyer un SIGKILL à un processus au moment même où il tente une action interdite, avant qu'elle ne soit complétée. C'est une différence majeure.
Développé par Isovalent (l'équipe derrière Cilium), Tetragon est nativement conscient de Kubernetes. Il comprend les pods, les namespaces, les labels, et peut corréler les événements du noyau avec les métadonnées Kubernetes sans configuration supplémentaire. Son architecture s'articule autour de TracingPolicies — des CRDs Kubernetes qui définissent quels événements noyau observer et quelles actions prendre.
L'approche complémentaire idéale : Falco pour la détection large et flexible, Tetragon pour le blocage chirurgical et l'observabilité profonde.
Installation de Tetragon sur Kubernetes
# Installation via Helm
helm repo add cilium https://helm.cilium.io
helm repo update
helm install tetragon cilium/tetragon \
--namespace kube-system \
--set tetragon.grpc.address="localhost:54321"
# Vérifier le déploiement
kubectl -n kube-system get pods -l app.kubernetes.io/name=tetragon
# Installer le CLI tetra pour l'analyse des événements
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
curl -L --remote-name-all \
https://github.com/cilium/tetragon/releases/latest/download/tetra-${GOOS}-${GOARCH}.tar.gz
tar xzf tetra-${GOOS}-${GOARCH}.tar.gz
sudo mv tetra /usr/local/bin/
Observer les événements de processus
Dès son installation, Tetragon commence à tracer l'exécution des processus avec un contexte Kubernetes complet. C'est assez impressionnant, honnêtement :
# Observer les événements de processus en temps réel
kubectl exec -n kube-system -it ds/tetragon -c tetragon -- \
tetra getevents -o compact
# Filtrer par namespace
kubectl exec -n kube-system -it ds/tetragon -c tetragon -- \
tetra getevents -o compact --namespace default
# Exemple de sortie :
# 🚀 process default/nginx-7b8d6c4f9-x2k4j /usr/sbin/nginx
# 🔌 connect default/nginx-7b8d6c4f9-x2k4j /usr/sbin/nginx tcp 10.0.0.5:80
# 💥 exit default/nginx-7b8d6c4f9-x2k4j /usr/sbin/nginx 0
Créer des TracingPolicies pour la détection et le blocage
Les TracingPolicies sont vraiment le cœur de Tetragon. Voici des exemples concrets de politiques de sécurité :
# tracing-policy-file-monitoring.yaml
# Surveiller les accès aux fichiers sensibles
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: surveillance-fichiers-sensibles
spec:
kprobes:
- call: "security_file_open"
syscall: false
args:
- index: 0
type: "file"
selectors:
- matchArgs:
- index: 0
operator: "Prefix"
values:
- "/etc/shadow"
- "/etc/passwd"
- "/etc/sudoers"
- "/root/.ssh/"
- "/var/run/secrets/kubernetes.io/"
matchActions:
- action: Post
# tracing-policy-block-execution.yaml
# Bloquer l'exécution de binaires suspects dans les conteneurs
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: bloquer-binaires-suspects
spec:
kprobes:
- call: "security_bprm_check"
syscall: false
args:
- index: 0
type: "path"
selectors:
- matchArgs:
- index: 0
operator: "Postfix"
values:
- "nmap"
- "masscan"
- "netcat"
- "ncat"
- "socat"
- "tcpdump"
matchNamespaces:
- namespace: Pid
operator: NotIn
values:
- "host_ns"
matchActions:
- action: Sigkill
# tracing-policy-network.yaml
# Surveiller et bloquer les connexions réseau suspectes
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: controle-connexions-reseau
spec:
kprobes:
- call: "tcp_connect"
syscall: false
args:
- index: 0
type: "sock"
selectors:
- matchArgs:
- index: 0
operator: "DPort"
values:
- "4444"
- "5555"
- "1337"
- "31337"
matchActions:
- action: Sigkill
- action: Post
# Appliquer les politiques
kubectl apply -f tracing-policy-file-monitoring.yaml
kubectl apply -f tracing-policy-block-execution.yaml
kubectl apply -f tracing-policy-network.yaml
# Vérifier les politiques actives
kubectl get tracingpolicies
kubectl describe tracingpolicy surveillance-fichiers-sensibles
Tester le blocage en temps réel
Bien sûr, on ne va pas se contenter de déployer des règles sans les tester. Vérifions que Tetragon bloque effectivement les binaires suspects :
# Lancer un pod de test
kubectl run test-security --image=alpine --restart=Never -- sleep 3600
# Tenter d'exécuter nmap (devrait être bloqué par Tetragon)
kubectl exec test-security -- apk add --no-cache nmap
kubectl exec test-security -- nmap -sP 10.0.0.0/24
# Résultat attendu : le processus est tué par SIGKILL
# Observer l'événement de blocage
kubectl exec -n kube-system -it ds/tetragon -c tetragon -- \
tetra getevents -o compact --namespace default
# 🚀 process default/test-security /usr/bin/nmap -sP 10.0.0.0/24
# 💥 exit default/test-security /usr/bin/nmap SIGKILL
# Nettoyer
kubectl delete pod test-security
Défense contre les menaces modernes : le cas VoidLink
Comprendre la menace
Parlons un peu plus en détail de VoidLink. Documenté par Check Point Research en janvier 2026, ce framework malveillant représente une nouvelle génération de malwares spécifiquement conçus pour les environnements cloud-natifs. Ses caractéristiques donnent froid dans le dos :
- Détection d'environnement : identification automatique du fournisseur cloud (AWS, GCP, Azure, Alibaba, Tencent) et du runtime (Docker, Kubernetes)
- Évasion de conteneur : modules dédiés exploitant des vulnérabilités connues du runtime pour accéder à l'hôte
- Rootkit eBPF : utilisation de programmes eBPF pour masquer ses propres processus, fichiers et connexions réseau
- C2 adaptatif : communication avec le serveur de contrôle via HTTP/HTTPS, WebSocket, ICMP tunneling ou DNS tunneling
- Modules compilés à la demande : le serveur C2 compile des modules noyau spécifiques à la version du kernel de chaque cible
En d'autres termes, c'est un malware qui s'adapte à son environnement de façon remarquablement intelligente.
Règles de détection spécifiques à VoidLink
Voici des règles Falco conçues pour détecter les indicateurs de compromission et les techniques utilisées par VoidLink :
# /etc/falco/rules.d/voidlink-detection.yaml
# Détection de chargement de programmes eBPF suspects
- rule: Chargement eBPF suspect dans un conteneur
desc: >
Détecte les tentatives de chargement de programmes eBPF
depuis un conteneur. VoidLink utilise eBPF pour masquer
ses processus et connexions.
condition: >
evt.type = bpf and
container and
not proc.name in (falco, tetragon, cilium-agent, datadog-agent)
output: >
Programme eBPF chargé depuis un conteneur (possible rootkit)
(processus=%proc.name commande=%proc.cmdline
conteneur=%container.name image=%container.image.repository
pod=%k8s.pod.name)
priority: CRITICAL
tags: [conteneur, ebpf, rootkit, voidlink]
# Détection d'accès aux métadonnées cloud
- rule: Accès suspect aux métadonnées cloud
desc: >
Détecte les requêtes vers le service de métadonnées cloud
(IMDS) depuis un conteneur. VoidLink interroge IMDS pour
identifier le provider et voler des credentials.
condition: >
outbound and
container and
fd.sip = "169.254.169.254" and
not k8s.ns.name in (kube-system, aws-system)
output: >
Accès aux métadonnées cloud depuis un conteneur
(processus=%proc.name conteneur=%container.name
image=%container.image.repository pod=%k8s.pod.name)
priority: CRITICAL
tags: [conteneur, cloud, credential_theft, voidlink]
# Détection de tunneling DNS
- rule: Tunneling DNS suspect
desc: >
Détecte les requêtes DNS avec des noms de domaine
anormalement longs, typiques du tunneling DNS utilisé
par VoidLink pour l'exfiltration de données.
condition: >
outbound and
container and
fd.sport = 53 and
evt.rawres > 512
output: >
Possible tunneling DNS détecté
(processus=%proc.name conteneur=%container.name
image=%container.image.repository pod=%k8s.pod.name)
priority: WARNING
tags: [conteneur, réseau, dns_tunneling, exfiltration, voidlink]
# Détection de manipulation de LD_PRELOAD
- rule: Manipulation LD_PRELOAD dans un conteneur
desc: >
Détecte la modification de la variable LD_PRELOAD ou du
fichier /etc/ld.so.preload. VoidLink utilise LD_PRELOAD
pour intercepter les appels de bibliothèque.
condition: >
(open_write and fd.name = "/etc/ld.so.preload" and container) or
(spawned_process and container and proc.env icontains "LD_PRELOAD")
output: >
Manipulation LD_PRELOAD détectée (technique de rootkit)
(fichier=%fd.name processus=%proc.cmdline
conteneur=%container.name image=%container.image.repository)
priority: EMERGENCY
tags: [conteneur, rootkit, ld_preload, voidlink]
TracingPolicy Tetragon anti-évasion
Pour compléter la détection Falco, voici une TracingPolicy Tetragon qui bloque activement les techniques d'évasion de conteneur :
# tracing-policy-container-escape-prevention.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: prevention-evasion-conteneur
spec:
kprobes:
# Bloquer les tentatives de chargement de modules noyau
- call: "security_kernel_module_request"
syscall: false
args:
- index: 0
type: "string"
selectors:
- matchNamespaces:
- namespace: Pid
operator: NotIn
values:
- "host_ns"
matchActions:
- action: Sigkill
# Bloquer les tentatives d'accès au namespace de l'hôte
- call: "security_task_setns"
syscall: false
args:
- index: 0
type: "nop"
selectors:
- matchNamespaces:
- namespace: Pid
operator: NotIn
values:
- "host_ns"
matchActions:
- action: Sigkill
- action: Post
Intégration dans un pipeline DevSecOps
Architecture de déploiement recommandée
Une stratégie de sécurité runtime complète ne vit pas en isolation — elle s'intègre dans un pipeline DevSecOps à plusieurs niveaux :
- Build time : scan des images de conteneurs (Trivy, Grype), génération de SBOM, signature des images (Cosign/Sigstore)
- Deploy time : admission controller validant les signatures et les politiques (Kyverno, OPA/Gatekeeper)
- Runtime : détection et réponse avec Falco + Tetragon
- Post-incident : analyse forensique avec les captures Falco et les logs Tetragon
Automatiser la réponse aux incidents avec Falcosidekick
Falcosidekick transforme les alertes Falco en actions concrètes et automatisées. Voici une configuration pour router les alertes critiques vers Slack et déclencher une quarantaine automatique des pods suspects :
# values-falcosidekick.yaml pour Helm
config:
slack:
webhookurl: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
minimumpriority: "warning"
messageformat: |
*Alerte Falco* : {{ .Rule }}
*Priorité* : {{ .Priority }}
*Sortie* : {{ .Output }}
*Namespace* : {{ index .OutputFields "k8s.ns.name" }}
*Pod* : {{ index .OutputFields "k8s.pod.name" }}
*Image* : {{ index .OutputFields "container.image.repository" }}
# Réponse automatisée via Kubernetes
kubernetesenrichment:
enabled: true
# Webhook personnalisé pour la quarantaine
webhook:
address: "http://incident-responder.security:8080/quarantine"
minimumpriority: "critical"
Et voici un script de quarantaine automatique. Le principe est simple : on isole le pod compromis via des labels et une NetworkPolicy qui coupe tout trafic :
# Script de réponse automatique : quarantaine d'un pod
#!/bin/bash
# quarantine-pod.sh - Isole un pod compromis en modifiant ses labels
# Appelé par le webhook Falcosidekick
POD_NAME=$1
NAMESPACE=$2
# Ajouter un label de quarantaine (les NetworkPolicies bloqueront le trafic)
kubectl label pod "${POD_NAME}" -n "${NAMESPACE}" \
security.linuxsecureops.com/quarantine=true --overwrite
# Annoter le pod avec le timestamp et la raison
kubectl annotate pod "${POD_NAME}" -n "${NAMESPACE}" \
security.linuxsecureops.com/quarantine-time="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
security.linuxsecureops.com/quarantine-reason="Falco alert triggered" \
--overwrite
# Appliquer une NetworkPolicy de quarantaine
cat << POLICY | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: quarantine-${POD_NAME}
namespace: ${NAMESPACE}
spec:
podSelector:
matchLabels:
security.linuxsecureops.com/quarantine: "true"
policyTypes:
- Ingress
- Egress
# Aucune règle = tout le trafic est bloqué
POLICY
echo "Pod ${POD_NAME} mis en quarantaine dans ${NAMESPACE}"
Tableau de bord et observabilité
Pour avoir une vision centralisée de ce qui se passe, intégrez Falco et Tetragon avec Prometheus et Grafana :
# Configuration Prometheus pour scraper les métriques Falco
# prometheus-config.yaml
scrape_configs:
- job_name: 'falco'
static_configs:
- targets: ['falco-falcosidekick.falco:2801']
metrics_path: /metrics
- job_name: 'tetragon'
static_configs:
- targets: ['tetragon.kube-system:2112']
metrics_path: /metrics
# Requêtes PromQL utiles pour le tableau de bord
# Nombre d'alertes Falco par priorité sur les dernières 24h
sum by (priority) (increase(falco_events_total[24h]))
# Top 10 des règles déclenchées
topk(10, sum by (rule) (increase(falco_events_total[1h])))
# Événements Tetragon par type
sum by (type) (rate(tetragon_events_total[5m]))
# Processus bloqués par Tetragon
sum by (namespace, pod) (increase(tetragon_policy_events_total{action="sigkill"}[1h]))
Bonnes pratiques et recommandations opérationnelles
Performance et optimisation
L'observation runtime, ça a un coût. Voici comment le maîtriser :
- Utilisez le driver eBPF moderne de Falco plutôt que le module noyau — il est plus performant et plus sûr
- Filtrez les événements au plus tôt : utilisez les listes et macros Falco pour exclure les processus système connus, et les sélecteurs Tetragon pour cibler uniquement les namespaces pertinents
- Limitez le volume de sortie : en production, n'activez que les règles pertinentes pour votre profil de risque. Les règles de type INFO génèrent un volume considérable (on parle de milliers d'événements par minute sur un cluster actif)
- Surveillez l'overhead : les métriques Falco exposent le taux de drops (événements perdus). Si ce taux dépasse 1 %, augmentez les ressources CPU/mémoire du DaemonSet
Stratégie de déploiement progressif
Un conseil d'expérience : ne déployez surtout pas toutes les règles en mode bloquant du premier coup. Suivez cette progression :
- Phase d'observation (2-4 semaines) : déployez Falco et Tetragon en mode détection uniquement. Collectez les alertes, identifiez les faux positifs, ajustez les règles. Cette phase est cruciale — ne la bâclez pas
- Phase de raffinement (1-2 semaines) : créez des listes d'exclusion pour les comportements légitimes. Testez les règles de blocage Tetragon en mode
Post(alerte sans blocage) - Phase d'enforcement : activez progressivement les actions
Sigkillde Tetragon, en commençant par les règles les plus fiables — chargement de modules noyau depuis un conteneur, exécution de binaires explicitement interdits - Phase d'automatisation : connectez Falcosidekick aux systèmes de réponse automatique pour les alertes CRITICAL et EMERGENCY
Gestion des faux positifs
Les faux positifs sont le principal défi opérationnel de la sécurité runtime. C'est ce qui fait que beaucoup d'équipes abandonnent ces outils prématurément. Voici comment les gérer efficacement :
# Créer des listes d'exclusion dans Falco
- list: processus_legitimes_admin
items: [ansible, puppet, chef-client, salt-minion, cloud-init]
- list: images_de_confiance
items:
- docker.io/library/nginx
- gcr.io/mon-projet/mon-app
- registry.k8s.io/
# Utiliser les listes dans les règles
- macro: processus_admin_autorise
condition: proc.name in (processus_legitimes_admin)
- macro: image_de_confiance
condition: container.image.repository in (images_de_confiance)
# Exemple de règle affinée avec exclusions
- rule: Shell dans un conteneur non autorisé
desc: >
Détecte l'exécution d'un shell dans un conteneur qui
n'est pas dans la liste des images de confiance.
condition: >
spawned_process and
container and
proc.name in (bash, sh, zsh) and
not image_de_confiance and
not processus_admin_autorise
output: >
Shell non autorisé dans un conteneur
(image=%container.image.repository commande=%proc.cmdline
pod=%k8s.pod.name namespace=%k8s.ns.name)
priority: WARNING
tags: [conteneur, shell]
Conformité et audit
Les événements collectés par Falco et Tetragon constituent une piste d'audit précieuse pour la conformité réglementaire :
- PCI DSS 4.0 : les exigences 10.2 et 10.3 imposent la journalisation des accès aux composants du système. Les alertes Falco sur les accès aux secrets et les modifications de fichiers système satisfont directement ces exigences
- SOC 2 : le principe CC6.8 exige la détection et la réponse aux vulnérabilités. L'architecture Falco + Tetragon avec réponse automatisée démontre un contrôle robuste
- NIS2 : la directive européenne impose la détection d'incidents et la notification sous 24 heures. Les alertes en temps réel de Falco, routées vers les équipes SOC via Falcosidekick, permettent de respecter ces délais
Pour l'archivage long terme des événements, configurez Falco pour écrire dans un stockage persistant :
# Configuration de sortie Falco vers fichier avec rotation
# /etc/falco/falco.yaml (extrait)
file_output:
enabled: true
keep_alive: false
filename: /var/log/falco/events.json
# Rotation des logs avec logrotate
# /etc/logrotate.d/falco
/var/log/falco/events.json {
daily
rotate 365
compress
delaycompress
missingok
notifempty
create 0640 root root
postrotate
systemctl reload falco > /dev/null 2>&1 || true
endscript
}
Conclusion : vers une sécurité runtime mature
La sécurité runtime des conteneurs Linux n'est plus un « nice to have » — c'est une nécessité face à des menaces comme VoidLink qui ciblent spécifiquement les environnements cloud-natifs. La combinaison de Falco pour la détection et de Tetragon pour le blocage au niveau du noyau constitue aujourd'hui la solution open source la plus solide disponible.
Les points clés à retenir :
- eBPF est le socle technique qui rend possible la sécurité runtime avec un overhead minimal et sans modification du noyau
- Falco et Tetragon sont complémentaires : Falco pour la détection et l'alerte, Tetragon pour l'application et le blocage
- Le déploiement progressif est essentiel : observation d'abord, blocage ensuite, après avoir éliminé les faux positifs
- L'automatisation de la réponse via Falcosidekick transforme la détection passive en défense active
- L'intégration DevSecOps garantit que la sécurité accompagne chaque étape du cycle de vie des conteneurs
Pour démarrer concrètement, déployez Falco en mode observation sur un cluster de staging. Laissez tourner deux à quatre semaines, affinez vos règles, puis introduisez Tetragon pour bloquer les comportements clairement malveillants. Et n'oubliez pas la signature d'images et les SBOM pour une sécurité de bout en bout. La route est longue, mais chaque étape compte.