2 minutes pour comprendre... eBPF

Sommaire
En 2 minutes #
Avec l’essort du cloud computing, les usages évoluent rapidement en matière de sécurité et de réseau. Il devient alors critique de pouvoir adapter rapidement le noyau Linux pour s’adapter à ces nouveaux besoins. Cependant, il est de notoriété publique qu’il est très compliqué, long, fastidieux et risqué de rajouter du code au noyau Linux, et à raison. Pour répondre à cette problématique, Extended BPF (eBPF) a été développé à partir de la technologie Berkeley Packet Filter (BPF). Bien plus qu’un outil de filtrage de paquets réseau (hérité de BPF), eBPF est un outil d’exécution de code arbitraire, sécurisé, isolé (“sandboxé”) et exécuté directement par le noyau Linux, sans pour autant avoir à modifier le code de ce dernier.
eBPF est devenu largement utilisé dans le domaine de l’observabilité, de la sécurité et du réseau, grâce à ses capacités de surveillance en temps réel des couches les plus basses du système. Hautement performant et sécurisé (grâce à l’isolation - ou “sandboxing”), il est notamment utilisé pour renforcer la sécurité des containers, améliorer le tracing et profiling, optimiser les performances réseau… tout ceci sans introduire de surcharge conséquente au noyau. Il est devenu l’outil de facto pour ajouter des fonctionnalités à la volée au noyau Linux.
La grande flexibilité d’eBPF lui permet d’être utilisé dans un nombre conséquent de contextes divers et variés, comme par exemple :
- tracing CPU, I/O et appels système (exemple : bpftrace)
- mise en réseau haute performance (exemple : cilium)
- détection de comportements anormaux ou “runtime security” (exemple : falco)
- profilage d’applications (exemple : ebpf_exporter)
En savoir plus… #
Fonctionnalités principales #
- compatibilité avec différents langages (Go, C/C++, Python, Rust, …)
- compatibilité avec différents noyaux (CO-RE)
- capture et introspection de paquets réseau
- interaction avec les couches bas niveau liées au réseau (FIB, TC, TCX, XDP, Sockets, …)
- collection, aggrégation et partage de traces et métriques (eBPF Maps)
- surveillance des appels système (syscalls)
- instrumentation des modules de sécurité Linux (LSM)
Architecture #

Techniquement, un programme eBPF est une suite d’instructions générées en bytecode à partir d’un autre langage. Ce bytecode est ensuite chargé dans le noyau via des appels système et attaché à des points spécifiques, appelés “hooks”. Il en existe de différent type, permettant aux programmes eBPF d’agir en conséquence de n’importe quel évènement traité par le noyau, mais également d’évènements non prédéfinis par le noyau. Parmi les “hooks” disponibles, on compte notamment :
- les appels système (syscalls)
- les entrées et sorties de fonction
- les tracepoints du noyau
- les évènements réseau
- les kprobes et uprobes, permettant d’attacher des points non prédéfinis

Avant d’être exécuté, le programme eBPF passe par un vérificateur intégré au noyau. Ce vérificateur garantit que le programme dispose des autorisations nécessaires, qu’il est sûr, qu’il ne contient pas de boucles infinies, qu’il respecte les limites de mémoire et qu’il ne peut pas planter le noyau. Une fois validé, le programme est exécuté dans un environnement isolé (“sandbox”), ce qui garantit qu’il ne peut pas compromettre la stabilité ou la sécurité du système.
Une fois validé, le bytecode eBPF est compilé en code machine natif par le compilateur JIT du noyau, permettant aux programmes eBPF de bénéficier des mêmes performances que le code natif du noyau ou des modules chargés dans ce dernier.

Afin de permettre aux programmes eBPF de stocker leur état et de partager des données entre eux ou avec l’espace utilisateur, différentes “maps” eBPF sont disponibles pour stocker et récupérer des données dans un large éventail de structures telles que (liste non exhaustive) :
- tables de hachage
- tableaux
- LRU
- Ring Buffer
- Stack Trace
- LPM

Dans un soucis de compatibilité, les programmes eBPF peuvent utiliser des fonctions appelées “helper functions”, faisant parti d’une API stable offerte par le kernel et permettant l’accès à des fonctions telles que (liste non exhaustive) :
- la génération de nombres aléatoires
- l’accès à la date et l’heure courante
- l’accès aux maps eBPF
- la manipulation de paquets réseau
Enfin, les programmes eBPF peuvent être composés grâce au concept de “tail calls” permettant d’exécuter d’autres programmes eBPF en fournissant un contexte d’exécution spécifique. Il est à noter que l’exécution d’un “tail call” est définitive puisque le programme appelant ne reprend jamais son exécution.
Ecosystème #
L’écosystème d’eBPF a considérablement évolué ces dernières années, devenant un pilier central pour la surveillance, la sécurité, et l’optimisation des systèmes Linux. Il repose sur une combinaison d’outils, de bibliothèques, de frameworks et de projets open source qui exploitent la puissance d’eBPF pour répondre à des besoins variés. Voici un aperçu des principaux éléments de cet écosystème :
- Noyau Linux : contient le runtime eBPF permettant l’exécution des programmes eBPF
- Compilateur LLVM : contient les ressources nécessaires à la compilation de programmes C en instructions eBPF
- Compilateur GCC : contient les ressources nécessaires à la compilation de programmes C++ en instructions eBPF
- bpftool : outil permettant d’inspecter et gérer les objets eBPF
- Cilium : projet open source fournissant des outils de réseau, de sécurité et d’observabilité basés sur eBPF et dédiés au projet Kubernetes
- bcc : collection d’outils et de bibliothèques pour écrire, charger et interagir avec des programmes eBPF
- Falco : outil de détection d’intrusion basé sur eBPF
- Calico : solution de mise en réseau et de sécurité open source pour les containers
- Pixie : plateforme d’observabilité pour Kubernetes, utilisant eBPF pour collecter des données sur les performances des applications et des containers
- Katran : load balancer de niveau 4 basé sur eBPF
- parca : profiler open source qui utilise eBPF pour collecter des données de profiling permettant d’identifier les problèmes de performance dans les applications
- Tetragon : outil de sécurité basé sur eBPF, développé par les créateurs de Cilium
- bpftrace : langage de haut niveau conçu pour écrire des scripts de traçage eBPF de manière simple et concise
Bon à savoir #
- hautement performant
- flexible et polyvalent
- écosystème en pleine croissance
- forte adoption par l’industrie
- courbe d’apprentissage élevée
- compatibilité avec les versions du noyau Linux (malgré CO-RE)
- limite de taille des programmes eBPF
- impact notable sur les ressources système en cas de mauvaise utilisation ou d’une grande quantité de programmes eBPF exécutés
- problème d’inter-compatibilité entre certains programmes
- debugging limité