Getty Images/iStockphoto

Réseau, sécurité, observabilité : l’essentiel sur eBPF

Avec eBPF, les développeurs peuvent rendre Linux programmable sans modifier le kernel. Découvrez les bases de cette technologie et comment elle peut être utilisée pour l’administration réseau, la supervision et la sécurité.

L’objectif derrière la programmabilité de l’OS est faussement simple. Il s’agit de permettre l’exécution de code supplémentaire sans modifier le code source du kernel et sans instituer de dépendances indésirables dans les modules.

Cette pratique n’est pas nouvelle. Les premiers concepts d’architecture virtualisée reposaient sur des ajustements du système d’exploitation pour supporter des formes de paravirtualisation. Mais chaque fois que vous ajoutez des spécifiques à un logiciel, vous pouvez créer des dépendances qui rendent difficile, voire impossible, la mise à jour du software sous-jacent. Lorsqu’une nouvelle version apparaît, le service IT doit retravailler et tester à nouveau les personnalisations existantes.

C’est le pire cauchemar du développeur.

Qu’est-ce qu’eBPF ?

En 2016, la version 4.4 du kernel Linux a introduit une nouvelle approche de la personnalisation appelée eBPF (extended Berkeley Packet Filter). Le kernel intègre un environnement sandbox, une machine virtuelle qui permet l’exécution du bytecode BPF, lequel peut affecter le kernel et utiliser ses ressources, sans le modifier.

Cette technologie est une évolution de BPF (Berkeley Packet Filter) présentée pour la première fois en 2013. Dès 1992, des chercheurs de l’université de Berkeley ont imaginé cet environnement sandbox pour abriter des filtres de paquets réseau. Avec eBPF, ses capacités sont étendues à d’autres pratiques de surveillance, de sécurité et mesure de performances que les administrateurs IT peuvent programmer directement ou acquérir auprès de sources tierces.

Pour comprendre le fonctionnement d’eBPF, l’on peut le comparer au développement Web. Le code HTML serait le noyau du système d’exploitation, et le site Web correspondrait aux services et aux comportements qui en résultent. Mais le HTML est notoirement statique, tout comme les services et les comportements que l’usager expérimente. L’ajout de JavaScript doit apporter la programmabilité et la flexibilité au site Web – de la même manière qu’eBPF le fait au niveau du kernel Linux.

Les programmes eBPF sont chargés dans la machine virtuelle au sein de l’environnement Linux et utilisent des événements déclencheurs spécifiques, baptisés crochets. Les hooks incluent les instances d’événements réseau, les traces et les fonctions du kernel. Lorsqu’un hook – également appelé déclencheur – est rencontré, le code eBPF correspondant est compilé, vérifié et exécuté. En clair, la technologie eBPF repose sur une LLVM, un compilateur JIT et un vérificateur.

L'environnement sandbox eBPF au sein du kernel Linux. .
L'environnement sandbox eBPF au sein du kernel Linux.

Le processus de vérification garantit que le programme eBPF est sûr. Il examine trois choses :

  • Le processus qui charge le programme eBPF doit avoir les privilèges pour le faire.
  • Le programme eBPF peut s’exécuter jusqu’au bout et ne tourne pas en boucle.
  • Le programme eBPF n’a pas d’effet négatif sur le kernel ou le système.

La vérification empêche généralement les problèmes de code eBPF accidentels ou malveillants.

En général, un programme eBPF ne suffit pas à lui seul à atteindre le kernel. Le programme eBPF s’appuie sur des fonctions supplémentaires du noyau, appelées appels d’aide (helper calls), qui lui donnent accès à des fonctions du kernel, par exemple à la mémoire. En fait, les appels d’aide forment une API qui permet aux programmes eBPF d’accéder au kernel.

Les appels d’aide incluent :

  • un générateur de nombres aléatoires
  • la manipulation de paquets réseau
  • l’accès à la date et à l’heure
  • l’accès aux ressources des processus Linux et des cgroups

En outre, les programmes eBPF collectent et partagent des informations stockées dans un large éventail de structures de données, appelées cartes eBPF. Les programmes eBPF accèdent à la fois aux cartes et aux applications utilisateur. Cela permet aux programmes eBPF de fournir des données aux autres applications de l’environnement.

Les cartes comprennent :

  • les tables de hash
  • les ring buffer
  • les traces de la stack

À quoi sert eBPF ?

Un programme eBPF accomplit des tâches relativement simples et directes qui demandent une charge ou un impact minimal sur l’environnement Linux. Les deux utilisations les plus courantes sont la mise en réseau et la surveillance, bien que la sécurité se développe également.

Mise en réseau

Comme tout système d’exploitation, Linux fournit un chemin réseau par défaut pour diriger les paquets vers leur destination. Chaque paquet doit traverser ce chemin.

Lorsqu’un programme eBPF est employé pour la mise en réseau, les paquets destinés à des destinations spécifiques peuvent contourner le chemin réseau par défaut et se déplacer directement vers la destination prévue. Cela améliore les performances du réseau et est souvent utilisé dans des environnements conteneurisés complexes pour optimiser le comportement des échanges entre microservices ou entre conteneurs. De même, eBPF peut appliquer une politique de réseau aux paquets, ce qui permet de router les paquets efficacement et d’appliquer des politiques au trafic.

Autre exemple, eBPF peut gérer l’équilibrage des charges à la source de la connexion, plutôt qu’au sein d’un système complexe de conteneurs. Dans ce dernier scénario, les professionnels de l’IT doivent effectuer une conversion des adresses IP virtuelles en adresses IP physiques via des passerelles NAT (Network Adress Translation). Certaines applications légères eBPF permettent d’éviter, voire d’éliminer le recours au NAT, ainsi que de diminuer les frais généraux et améliorer les performances du réseau.

Supervision

Le plus souvent, l’eBPF est associé à un type de monitoring appelé observabilité : les organisations IT doivent collecter des statistiques sur les fonctions clés du kernel Linux, telles que le nombre d’appels et le processus qui a effectué ces appels.

En outre, un module eBPF peut modifier les données traitées par une fonction, ce qui permet de prétraiter, de normaliser ou de manipuler plus aisément les données, afin de permettre aux administrateurs de mieux comprendre l’environnement Linux.

Sécurité

Les programmes eBPF sont utiles pour les environnements sensibles au temps, hautement distribués et basés sur des conteneurs, où les tactiques traditionnelles de surveillance de la sécurité ne fonctionnent pas vraiment. Dans des environnements tels que Kubernetes, eBPF peut offrir une visibilité granulaire du trafic HTTP, que la surveillance traditionnelle de la sécurité pourrait manquer. En outre, eBPF peut également être utilisé pour la sécurité dans les pare-feu (en remplacement des tables IP traditionnelles), les pilotes de périphériques et la surveillance de l’activité réseau.

Comment eBPF est-il adossé au kernel ?

Linux 4.4 et les versions suivantes prennent en charge eBPF. Cependant, les versions du noyau 4.9 et suivantes offrent plus de maturité. Par exemple, Red Hat Enterprise Linux 7.6 utilise un noyau plus ancien et introduit eBPF en tant qu’aperçu technologique. Bien que la prise en charge d’eBPF soit déjà disponible, le processus réel d’élaboration de programmes eBPF est plus compliqué. La conception de modules eBPF ressemble à la programmation en code assembleur et les limitations sont fortes : les boucles sont détectées et interdites par la validation eBPF. Cependant, divers outils aident les développeurs à bâtir des runtimes eBPF, par exemple :

  • BPF Compiler Collection (BCC) prend en charge la création de programmes eBPF dans les environnements Python et Lua.
  • eBPF Go Library offre des outils permettant de charger, compiler et déboguer des runtimes eBPF.
  • Libbpf contient un chargeur eBPF pour traiter les fichiers eBPF générés par la Low-Level Virtual Machine (LLVM) pour les charger dans le noyau.
  • LLVM, un kit pour assembler des programmes eBPF en C.

Il existe également plusieurs projets qui impliquent ou proposent des programmes et des projets eBPF :

  • Bpftrace fournit un langage de traçage de haut niveau.
  • Cilium fournit divers outils eBPF pour la mise en réseau, la surveillance et la sécurité.
  • Falco est un moteur de détection de vulnérabilités dans les conteneurs Linux basés sur eBPF.
  • Katran fournit un équilibreur de charge de couche 4 basé sur eBPF.
  • Pixie fournit des outils de surveillance pour les clusters Kubernetes basés sur eBPF.

Les défis de l’implémentation d’eBPF

Compte tenu des risques inhérents aux modifications du système d’exploitation, les créateurs d’eBPF se sont donné beaucoup de mal pour sécuriser la plateforme par le biais de privilèges, de vérifications et de durcissements. Par exemple, seuls les processus dotés des privilèges root peuvent charger les programmes eBPF – à moins que vous n’activiez l’eBPF non privilégié – ce qui empêche les applications non fiables de charger les programmes eBPF.

De même, le processus de vérification garantit que tous les programmes eBPF sont sûrs et respectent les règles eBPF, telles que l’absence de boucles, les limites de taille ou de complexité, ainsi que les restrictions de variables. Enfin, le programme eBPF est renforcé pour protéger la mémoire le contenant, ainsi que pour lier les constantes et endiguer les prédictions de branchement CPU, afin d’éviter des vecteurs d’attaque possibles.

Bien que l’eBPF soit un moyen puissant et efficace de profiter des capacités du kernel Linux, cette technologie peut comporter des risques et des frustrations pour les développeurs. La technologie a déjà fait l’objet de plusieurs notes CVE signalant des failles depuis corrigées. De plus, eBPF n’est pas adapté à tous les projets ou situations. Par exemple, l’environnement ne fonctionne qu’avec les noyaux Linux récents, le code n’est donc pas facilement portable vers d’autres OS ou projets.

En outre, les fonctions de sécurité qui protègent l’exécution du programme eBPF restreignent également la fonctionnalité eBPF, et ces limites doivent être suivies tout au long du développement et du déploiement d’un programme eBPF.

Pour approfondir sur Linux