EBPF pour observabilité et enforcement Linux
- Accueil
- Fondations
- Réseaux
- EBPF pour observabilité et enforcement Linux
EBPF pour observabilité et enforcement Linux
Section intitulée « EBPF pour observabilité et enforcement Linux »eBPF (extended Berkeley Packet Filter) exécute des programmes courts dans le noyau Linux, attachés à des événements réseau, système ou applicatifs, sans modifier les sources du noyau ni charger un module classique. Le gain est brutal : visibilité et contrôle au plus près de l’événement ; le prix est une dépendance forte aux versions du noyau, aux privilèges de chargement et à une chaîne d’exploitation qui ne tolère pas l’improvisation.
eBPF ressemble à un poste de contrôle installé à l’entrée d’une ville : il peut compter les passages, repérer des comportements suspects et bloquer certains véhicules avant qu’ils encombrent les rues. Il sert à observer ce qui se passe réellement et à appliquer des règles sans reconstruire toute la ville.
→ Lire l’explication complète de la marmotte
Exécution eBPF dans le noyau Linux
Section intitulée « Exécution eBPF dans le noyau Linux »Un programme eBPF est un bytecode chargé dans le noyau, puis attaché à un point d’accroche : réception d’un paquet, appel système, fonction noyau, événement de planification ou point de trace applicatif. Le noyau peut compiler ce bytecode avec un compilateur JIT (Just-In-Time) vers des instructions machine. Le programme s’exécute alors dans le contexte de l’événement observé, sans changement de code du noyau et sans cycle de compilation de module.
Ce modèle ne transforme pas eBPF en zone franche dans le noyau. Le chargeur fournit le programme, ses cartes et son type d’attachement ; le vérificateur accepte ou refuse l’ensemble avant exécution. Les cartes eBPF stockent l’état partagé : compteurs, tables de flux, listes d’adresses, règles de décision ou événements destinés à l’espace utilisateur. Elles sont le contrat entre le plan de données dans le noyau et le plan de contrôle hors noyau.
Les principaux points d’accroche réseau sont XDP (eXpress Data Path), au plus tôt dans la réception d’une trame, et TC (Traffic Control), dans les couches de traitement réseau Linux. XDP est le bon choix pour rejeter très tôt un trafic connu comme indésirable ou pour répartir des flux à haut débit. TC voit davantage de contexte réseau et couvre aussi la sortie. Pour les processus, les tracepoints et les hooks LSM (Linux Security Modules) donnent accès aux appels système, aux créations de processus, aux opérations sur les fichiers et à certaines décisions de sécurité.
La recommandation est nette : utiliser eBPF pour les chemins critiques où l’observation ou la décision doit précéder la copie du paquet vers l’espace utilisateur. Ne pas le choisir pour remplacer mécaniquement chaque démon de supervision. Déplacer une métrique lente dans le noyau parce que le mot eBPF figure sur une slide reste une optimisation de carrière, pas une architecture.
Côté plateforme, viser au minimum un noyau Linux 6.1 LTS (Long Term Support) ou plus récent pour une base fonctionnelle cohérente. Vérifier les capacités réellement exposées par la distribution : les rétroportages rendent le numéro de version insuffisant. La présence de BTF (BPF Type Format) dans /sys/kernel/btf/vmlinux, de cgroup v2 (control group version 2) et du système de fichiers bpffs monté sur /sys/fs/bpf évite une large collection de contournements fragiles. Pour construire des programmes portables, utiliser Clang, LLVM (Low Level Virtual Machine) et libbpf avec CO-RE (Compile Once Run Everywhere), qui adapte les accès aux structures noyau grâce aux métadonnées BTF.
Vérificateur eBPF : garantie mémoire, pas preuve de sécurité métier
Section intitulée « Vérificateur eBPF : garantie mémoire, pas preuve de sécurité métier »Le vérificateur analyse chaque chemin d’exécution avant chargement. Il contrôle les types de pointeurs, la taille des accès mémoire, l’initialisation des registres, les appels aux helpers autorisés et la terminaison des boucles. Un accès hors limites à une carte, un déréférencement de pointeur non fiable ou une boucle dont la borne ne peut pas être démontrée provoquent un refus. Cette contrainte est précisément ce qui distingue eBPF d’un module noyau : le code ne reçoit pas un permis de casser la mémoire parce qu’il a été compilé avec aplomb.
Les boucles bornées sont admises sur les noyaux modernes, mais leur borne doit être vérifiable. Une longueur reçue du réseau ne devient pas magiquement sûre parce qu’elle est stockée dans une variable bien nommée. Le vérificateur suit les bornes, les branches et l’état des registres. Lorsque le nombre d’états explorés explose, il refuse aussi le programme. Ce refus n’est pas une vexation personnelle du noyau, même si le journal de vérification peut donner cette impression à trois heures du matin.
Cette vérification ne garantit pas l’intention de sécurité. Un programme eBPF peut lire une carte contenant une liste d’autorisation erronée, associer mal une identité à un paquet, ou envoyer des événements sensibles à un consommateur insuffisamment protégé. Elle ne prouve ni l’absence de vulnérabilité dans un helper noyau, ni l’absence de défaut dans le compilateur JIT, ni la pertinence d’une règle de détection. Elle protège principalement l’intégrité mémoire et la terminaison du programme, pas le modèle de menace.
Le chargement est donc une frontière d’administration. Restreindre les capacités Linux nécessaires, notamment CAP_BPF, CAP_PERFMON et CAP_NET_ADMIN selon le type de programme. Les noyaux anciens reposent plus largement sur CAP_SYS_ADMIN, capacité beaucoup trop vaste pour servir de rôle eBPF. Désactiver eBPF non privilégié lorsque le poste ou le serveur ne l’exige pas, activer le mode verrouillage BPF après initialisation lorsque l’exploitation le permet, et ne jamais donner l’écriture sur bpffs à un conteneur applicatif. Une carte modifiable est une politique modifiable, ce qui n’est pas un détail cosmétique.
XDP, Cilium et filtrage réseau à haut débit
Section intitulée « XDP, Cilium et filtrage réseau à haut débit »iptables traite historiquement les paquets dans Netfilter, avec des chaînes de règles évaluées dans la pile réseau. nftables a remplacé son modèle interne et doit rester le choix généraliste sur les hôtes Linux. eBPF ne remplace pas universellement iptables : il remplace avantageusement des portions de filtrage, de routage et d’équilibrage quand la décision doit arriver avant le coût de la pile réseau ou quand une politique dépend d’un état riche conservé dans des cartes.
XDP peut retourner XDP_DROP avant allocation de structures réseau coûteuses. C’est adapté aux listes de blocage, à la limitation élémentaire de débit, au rejet de paquets malformés et à certains équilibrages de charge. Il ne remplace pas une inspection applicative HTTP (Hypertext Transfer Protocol), ni une politique qui exige la réassemblage complet d’un flux TCP (Transmission Control Protocol). Vouloir analyser un protocole applicatif complexe dans XDP mène vite à un programme refusé, lent ou faux. Les trois options ne sont pas exclusives : nftables pour la politique hôte générale, XDP pour le filtrage précoce, proxy pour la sémantique applicative.
Cilium exploite eBPF comme plan de données pour Kubernetes et ses réseaux de conteneurs. Il fournit connectivité, politiques réseau, visibilité des flux et parfois remplacement des règles kube-proxy reposant sur iptables. Son apport concret est de lier une identité de charge de travail à la politique, plutôt qu’une suite de règles fondées uniquement sur les adresses IP (Internet Protocol), lesquelles changent constamment en orchestration. Cette identité n’est fiable que si la chaîne d’admission Kubernetes, le CNI (Container Network Interface) et les comptes de service sont durcis. Une politique eBPF parfaite ne répare pas un cluster où tout pod peut obtenir un jeton d’administration.
Les architectures réseau doivent aussi conserver une télémétrie exportable. Les compteurs de cartes eBPF ne remplacent pas les journaux de décision, les flux réseau ni les alertes corrélées. La page réseaux et celle sur les menaces complètent ce niveau de contrôle avec les mécanismes de détection et de réponse hors du noyau.
Trace d’appels système et Falco pour la détection
Section intitulée « Trace d’appels système et Falco pour la détection »Les tracepoints d’appels système permettent de voir un execve, une ouverture de fichier, une connexion sortante ou une élévation de privilège au moment où l’événement se produit. Un IDS (Intrusion Detection System) fondé sur ces événements peut repérer un shell lancé par un processus inattendu, l’écriture dans un répertoire sensible ou un binaire exécuté depuis une zone temporaire. L’absence d’instrumentation du code applicatif est précieuse : une charge compromise ne coopère généralement pas avec le système d’observabilité, cette surprise ne mérite aucun prix d’innovation.
Falco collecte notamment ces événements via eBPF et applique des règles de détection. Par rapport à l’analyse de journaux, il observe des actions qui peuvent ne jamais atteindre le journal applicatif. Par rapport à un agent fondé sur un module noyau, il réduit le code privilégié spécifique à maintenir. Falco n’est toutefois pas une barrière d’exécution universelle : ses règles produisent surtout des alertes. Pour bloquer, utiliser les hooks LSM ou une politique réseau, avec une règle de repli explicite.
Le piège majeur est le volume. Une sonde qui exporte chaque appel système vers l’espace utilisateur peut saturer les buffers, perdre des événements et déclencher une crise de confiance envers la détection. Filtrer dans le programme eBPF, agréger les compteurs et exporter seulement les événements enrichis. Toute perte doit être mesurée : une sonde incapable d’indiquer ses pertes est un générateur de silence décoratif.
Exemple reproductible : tracer les exécutions de processus
Section intitulée « Exemple reproductible : tracer les exécutions de processus »Le test suivant utilise bpftrace, un outil qui compile une expression de traçage en programme eBPF. Il exige un noyau avec tracepoints, le paquet bpftrace, ainsi que les privilèges de traçage appropriés. Il observe, il ne bloque rien.
# Afficher chaque appel execve avec le processus appelant et le binaire demandé.# Arrêter avec Ctrl+C. Exécuter dans un environnement de test supervisé.sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve{ printf("pid=%d comm=%s fichier=%s\n", pid, comm, str(args->filename));}'La commande est utile pour valider la visibilité, pas pour construire une règle de sécurité. Le champ filename peut être incomplet selon le contexte, un chemin peut être renommé après ouverture, et l’exécutable réel peut provenir d’un descripteur de fichier. Une détection sérieuse corrèle l’identifiant du processus, le parent, l’espace de noms, l’identité de conteneur et, lorsque nécessaire, le hash du binaire obtenu hors du chemin critique.
Exploitation : clés, mises à jour et reprise
Section intitulée « Exploitation : clés, mises à jour et reprise »Les programmes eBPF, leurs cartes épinglées et les règles de plan de contrôle sont des actifs de sécurité. Signer les artefacts de build, contrôler leur provenance dans la chaîne CI/CD (Continuous Integration and Continuous Delivery), et journaliser le hash du bytecode chargé. Il n’existe pas de signature eBPF universellement imposée par le noyau : la confiance doit venir de la distribution des artefacts, des droits de chargement et de l’intégrité de l’hôte.
Prévoir la rotation des listes de blocage, identités, certificats de mTLS (mutual Transport Layer Security) et jetons utilisés par le contrôleur. Une carte épinglée survit souvent au redémarrage du processus de contrôle, pas nécessairement au redémarrage de l’hôte. Sauvegarder la configuration déclarative et reconstruire l’état dérivable ; ne pas traiter le contenu brut des cartes comme une sauvegarde suffisante. Les compteurs peuvent être perdus, les règles ne doivent pas l’être.
Surveiller les refus du vérificateur, les erreurs de chargement, les pertes d’événements dans les buffers circulaires, la saturation des cartes et le coût processeur par point d’accroche. Tester les mises à jour de noyau avec les programmes réellement chargés : le modèle CO-RE réduit la friction, il n’abolit pas les changements de comportement. Le plan de reprise doit préciser ce qui arrive si le contrôleur disparaît : conserver la dernière politique, basculer en refus, ou repasser à nftables. Laisser ce choix implicite revient à confier la sécurité à l’ordre de redémarrage, discipline célèbre pour son sens de l’humour.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans point d’observation dans le noyau, la connaissance des événements dépend de ce que les applications acceptent de journaliser : un processus compromis cesse d’alimenter sa propre trace, et rien ne le contredit. Les exécutions très brèves échappent aux collectes périodiques qui lisent /proc, si bien qu’un binaire lancé puis supprimé ne laisse aucune filiation exploitable. Le filtrage tardif oblige à allouer des structures réseau pour chaque paquet destiné au rejet, ce qui transforme un flux volumétrique en coût processeur. En orchestration, la politique retombe sur des adresses IP réattribuées d’une charge à l’autre, donc l’attribution après coup devient approximative. Enfin, aucune décision ne peut être prise avant l’appel système : il reste l’alerte tardive, jamais le blocage.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Un programme eBPF est un petit programme envoyé au noyau Linux, la partie du système qui gère directement le matériel, les processus et le réseau. Avant de l’accepter, Linux examine toutes ses instructions. Il vérifie que le programme finit toujours, qu’il ne lit pas ou n’écrit pas en dehors des zones mémoire autorisées, et qu’il n’utilise que les opérations permises. Si une boucle peut durer sans limite ou si un accès mémoire paraît dangereux, le chargement échoue avant toute exécution.
Une fois accepté, le programme est déclenché par un événement choisi : arrivée d’un paquet réseau, lancement d’un processus, ouverture d’un fichier ou appel demandé au système. Il peut compter, enregistrer un événement, consulter une liste de règles ou demander le rejet d’un paquet. Des zones de stockage partagées conservent les compteurs et les règles entre les exécutions.
Cette méthode permet de détecter rapidement des actions suspectes et de filtrer du trafic avant des traitements coûteux. Elle ne garantit pas que les règles sont bonnes, qu’une alerte sera lue, ni qu’un administrateur autorisé ne chargera pas un programme mal conçu. Les droits de chargement, la surveillance des erreurs, la sauvegarde des règles et le test après mise à jour du noyau restent donc nécessaires.
À lire aussi
- EBPF pour observer et bloquer dans le noyau LinuxeBPF permet d’observer et d’appliquer des politiques dans le noyau Linux, sous réserve de maîtriser ses privilèges, ses programmes et son exploitation.
- Linux : définition, origine et rôle du noyauDéfinition de Linux : noyau système créé par Linus Torvalds en 1991, sous licence GPLv2, ce qu'il fait concrètement et pourquoi il équipe serveurs, Android et supercalculateurs.
- Debian stable sur serveur, mises à jour de sécurité et rétroportagesCe que la branche stable de Debian garantit sur un serveur, comment les correctifs de sécurité y arrivent automatiquement, ce que valent les rétroportages et où s'arrête la promesse.
- Linux shell, permissions et processus, le modèle de contrôle d'accèsComment un système Linux décide qui a le droit de faire quoi, du shell qui lance les processus aux identités, permissions et capabilities que ces processus portent.
Pages voisines
La citent
- Linux : définition, origine et rôle du noyau
- Conteneurs, Kubernetes, CNI et service mesh
- EDR : fonctionnement, angles morts et contournements
EBPF pour observabilité et enforcement Linux
Elle cite
