Comment gérer efficacement XDP/EBPF pour une meilleure protection DDOS

Le filtre de paquets étendu de Berkeley ( eBPF ) peut être mis à jour rapidement et en continu, ce qui le rend idéal pour gérer les changements fréquents de configuration de sécurité.

Traduit de Comment gérer efficacement XDP/eBPF pour une meilleure protection DDoS , auteur Ivan Koveshnikov.

La carte Extended Berkeley Packet Filter ( eBPF ) sert d'interface de haut niveau pour les mises à jour atomiques des segments de mémoire partagée utilisés comme mémoire partagée et fournit une interface de configuration puissante pour les programmes eBPF. Le mécanisme de lecture-copie-mise à jour minimise la surcharge de performances dans le hot path. De plus, le mappage eBPF permet un accès exclusif aux segments de mémoire partagée. Ils peuvent gérer des types de cartes mixtes (tableaux, tables de hachage, filtres Bloom, files d'attente et tampons en anneau), ce qui les rend idéaux pour les configurations complexes telles que la sécurité .

À mesure que la complexité de la configuration augmente, le besoin de connexions entre les différentes entrées de mappage augmente également. S'il existe trop de connexions entre les entrées de carte, la capacité à effectuer des mises à jour de configuration atomiques commence à se dégrader. La mise à jour d'une seule entrée de carte peut signifier que d'autres entrées doivent être mises à jour en même temps, ce qui peut entraîner des incohérences lors des mises à jour.

Appliquez XDP pour une gestion avancée du trafic

Considérons un simple programme eXpress Data Path (XDP) qui classe et filtre le trafic en fonction d'un ensemble de règles prioritaires à cinq tuples. Le programme traite le paquet suivant en fonction de la priorité de la règle et d'une combinaison de l'adresse IP source, de l'adresse IP de destination, du protocole et des ports source et destination du paquet.

Organigramme de classification menant au traitement

Organigramme de classification menant au traitement.

Voici un exemple de règle de configuration réseau :

  1. Tout trafic provenant du sous-réseau A est toujours autorisé.
  2. Empêchez les clients du sous-réseau C d'accéder au serveur Web du sous-réseau B.
  3. Restreindre l'accès au serveur Web dans le sous-réseau B.
  4. Tout autre accès est refusé.

Ces règles nécessitent que les règles et restrictions de classification du trafic soient stockées dans la configuration, ce qui peut être réalisé à l'aide des mappages eBPF.

Comprendre la configuration du programme eBPF sous forme d'arborescence

Vous pouvez visualiser la configuration sous forme d'arborescence hiérarchique, avec une « racine de configuration » comme base. Cette racine (éventuellement virtuelle) organise les différentes entités de configuration pour former la configuration active. Les entités sont soit directement connectées à la racine pour un accès global immédiat, soit imbriquées dans d'autres entités pour une organisation structurée.

L'accès à une entité spécifique commence à la racine et se déroule séquentiellement ("déréférencement" de chaque niveau) jusqu'à ce que l'entité souhaitée soit atteinte. Par exemple, pour récupérer un indicateur booléen à partir d’une structure « options » dans une collection, vous devez accéder à la collection, rechercher la structure, puis récupérer les indicateurs.

L'approche de Gcore pour relever les défis de complexité de l'eBPF

Cette structure arborescente offre une flexibilité dans la gestion de la configuration, y compris l'échange atomique de n'importe quel sous-arbre, garantissant des transitions fluides et sans interruption. Cependant, une complexité accrue entraîne des défis. À mesure que les configurations deviennent plus complexes, les entrées deviennent plus interconnectées. Il est courant que plusieurs entrées parent pointent vers une seule entrée enfant, ou qu'une entrée joue un double rôle, à la fois en tant que propriété d'une entité et en tant que partie d'une collection.

Les langages de programmation modernes ont développé des mécanismes pour gérer des configurations complexes. Les développeurs utilisent des compteurs de références, des références mutables et immuables et des garbage collectors pour garantir des mises à jour sécurisées. Cependant, gérer la sécurité de ces configurations ne garantit pas l’atomicité lors du basculement entre les versions de configuration.

Le paysage en constante évolution du trafic en ligne signifie que les équipes chargées des opérations de sécurité doivent apporter des modifications fréquentes aux politiques de sécurité. Par conséquent, Gcore a effectué des mises à jour rapides et fréquentes de la protection Gcore DDoS et a incorporé des fonctionnalités importantes telles qu'un moteur d'expression régulière . Nous sommes passés du standard d'une ou deux mises à jour par jour pour les solutions auto-hébergées aux mises à jour quasi constantes requises par les fournisseurs de services. Cette exigence, souvent négligée dans les applications Linux, a conduit à l'adoption de la technologie eBPF, qui permet des mises à jour rapides et ininterrompues.

Lorsque nous explorons les solutions eBPF, nous devons explorer en profondeur les stratégies pour garantir que notre configuration eBPF est gérée de la meilleure façon possible. Plus précisément, les limites du mappage eBPF ont amené notre équipe à repenser notre stratégie de stockage de configuration.

En raison de la validation de la sécurité du noyau, les entrées de carte eBPF ne peuvent pas stocker de pointeurs directs vers des segments de mémoire arbitraires, ce qui nécessite une clé de recherche pour accéder à l'entrée de carte, ce qui ralentit le processus de recherche. Mais cette lacune présente un avantage : elle nous permet de diviser les arborescences de configuration complexes en segments plus petits et plus gérables, liés directement à la racine de configuration. quel est le résultat ? Cohérence, même lors des mises à jour non atomiques.

Nos résultats et stratégies soulignent l’importance d’une planification et d’une exécution minutieuses des programmes eBPF pour optimiser l’efficacité. Passons maintenant aux stratégies de mise à jour de configuration spécifiques pour les environnements eBPF et à leur applicabilité aux exigences et limitations uniques du système.

Politique de mise à jour de la configuration de sécurité

Nous avons trouvé trois stratégies de mise à jour particulièrement efficaces pour améliorer les mises à jour du programme tout en garantissant des performances et une flexibilité élevées.

Stratégie de mise à jour 1 : Transition progressive

Une stratégie de mise à jour progressive signifie des mises à jour de configuration incrémentielles sur plusieurs mappages. Il s'agit d'une option utile lors du traitement des données d'une carte afin de fournir une clé de recherche pour une autre carte. Dans ce cas, plusieurs entrées de carte doivent être mises à jour et la conversion atomique n'est pas réalisable. Mais des opérations de mise à jour précises et séquentielles permettent une mise à jour méthodique de la configuration. Certaines opérations sur les sous-arbres de configuration référencés deviennent sûres si elles sont effectuées dans le bon ordre.

Par exemple, dans le contexte de la classification et du traitement, la couche de classification fournit des clés de recherche pour faire correspondre les politiques de sécurité, ce qui signifie que les opérations de mise à jour doivent suivre un ordre spécifique :

  • Il est possible d'insérer une nouvelle stratégie de sécurité en toute sécurité car la nouvelle stratégie n'a pas encore été référencée.
  • Il est également sûr de mettre à jour les politiques de sécurité existantes, car les mettre à jour individuellement ne pose généralement pas de problèmes. Bien que les mises à jour atomiques soient souhaitables, elles n’apportent pas d’avantages significatifs.
  • Il est possible de mettre à jour en toute sécurité le mappage de la couche de classification pour faire référence à la nouvelle stratégie de sécurité et supprimer les références à la stratégie obsolète.
  • Il est possible de purger en toute sécurité les politiques de sécurité inutilisées de la configuration une fois qu'elles ne sont plus référencées.

Même sans mises à jour atomiques, des mises à jour sécurisées peuvent être effectuées en séquençant correctement le processus de mise à jour. Cette méthode fonctionne mieux pour les mappages autonomes qui ne sont pas étroitement liés à d’autres mappages.

Nous vous recommandons d'effectuer des mises à jour incrémentielles plutôt que de mettre à jour la carte entière en une seule fois. Par exemple, les mises à jour incrémentielles des cartes de hachage et des tableaux sont totalement sécurisées. Toutefois, ce n’est pas le cas pour les mises à jour incrémentielles d’une carte LPM (Longest Prefix Match), car la recherche dépend des éléments déjà présents dans la carte. Le même problème se produit lorsque la création d’une clé de recherche pour une autre table nécessite d’opérer sur des éléments de plusieurs cartes.

Les couches de classification sont souvent implémentées à l'aide de plusieurs LPM et tables de hachage, fournissant un exemple de cette complexité :

La recherche s'effectue de la classification au LPM et au hachage, et de la classification au traitement jusqu'au hachage, avec une description du problème de mise à jour du mappage.

Stratégie de mise à jour 2 : remplacement de la cartographie

Pour les mappages qui ne peuvent pas être mis à jour de manière incrémentielle sans incohérence (tels que les mappages LPM), le remplacement de l'intégralité du mappage est la meilleure solution. Pour remplacer le mappage du programme eBPF, vous avez besoin d'un mappage du mappage. Une application en espace utilisateur peut créer une nouvelle carte, la remplir avec les entrées nécessaires, puis remplacer atomiquement l'ancienne carte.

Le mappage mappé donne naissance à deux nœuds dotés de capacités d'isolation et de remplacement des ressources.

Le partitionnement de la configuration en cartes distinctes, chacune décrivant les paramètres d'une seule entité, offre l'avantage supplémentaire de l'isolation des ressources et élimine le besoin de recréer la configuration complète lors de mises à jour mineures. La configuration de chaque entité multiple peut être stockée dans une carte remplaçable.

Cette méthode présente certains inconvénients. L'espace utilisateur doit désépingler le mappage précédent pour conserver le chemin fixe précédent, car le mappage de remplacement ne peut pas être épinglé au même emplacement que le mappage précédent. Ceci est particulièrement important pour les programmes à long terme qui mettent fréquemment à jour leur configuration et s’appuient sur l’épinglage de carte pour leur stabilité.

Stratégie de mise à jour 3 : remplacement du programme

La méthode de remplacement de carte peut échouer lors de la liaison de plusieurs cartes entre elles. La seule mise à jour du mappage peut entraîner un état incohérent ou invalide qui ne reflète ni l'ancienne configuration ni la nouvelle configuration attendue.

Pour résoudre ce problème, les mises à jour atomiques devraient avoir lieu à un niveau supérieur. Bien qu'eBPF ne dispose pas d'un mécanisme permettant de remplacer atomiquement un ensemble de mappages, les mappages sont généralement liés à un programme eBPF spécifique. Ce problème peut être résolu en divisant les mappages interconnectés et le code correspondant en programmes eBPF distincts liés par des appels de queue.

Pipeline de paquets vers organigramme de mappage de programme, résultant en des packages de code et de mappage remplaçables pour les programmes eBPF.

Pour y parvenir, il faut charger un nouveau programme eBPF, créer et remplir le mappage correspondant, épingler les deux, puis mettre à jour le mappage du programme à partir de l'espace utilisateur. Ce processus est plus laborieux qu'un simple remplacement de mappage, mais il permet de mettre à jour simultanément le mappage et le code associé, facilitant ainsi les ajustements du code d'exécution. Cependant, l'utilisation de cette approche n'est pas toujours particulièrement efficace, en particulier lors de l'utilisation de plusieurs cartes et sous-programmes pour mettre à jour une seule entrée de carte dans un programme complexe.

La gestion des erreurs

La gestion des erreurs lors de la gestion de l’eBPF peut être délicate. Il est important de mettre à jour la configuration pour éviter les incohérences. Si une erreur se produit lors d'une mise à jour, cela peut provoquer le chaos. Des sauvegardes automatisées peuvent donc contribuer à réduire le besoin de correctifs manuels.

Vous pouvez diviser les erreurs en deux catégories : les erreurs récupérables et les erreurs irrécupérables. Pour les erreurs récupérables, si quelque chose ne va pas lors d’une mise à jour, vous pouvez simplement l’arrêter et aucune modification ne sera apportée. Vous pouvez corriger n’importe quel bug sans risque.

Les erreurs irrécupérables sont un peu plus délicates. Vous devez les manipuler avec précaution car ils peuvent affecter des entités de configuration spécifiques, ce qui peut interrompre l'ensemble du système.

Il est préférable d'organiser les mises à jour par entité de configuration plutôt que par type de mise à jour. De cette façon, si une erreur se produit, elle n’affecte qu’une entité de configuration spécifique et pas tout en même temps. Par exemple, si des règles de classification et des politiques de sécurité sont définies pour différents segments de réseau, il serait plus efficace de les mettre à jour dans des cycles distincts basés sur le segment de réseau plutôt que par type de mise à jour. Cela facilite la gestion des sauvegardes automatisées et si une erreur irrécupérable se produit, vous saurez exactement quel en est l'impact. Seule une partie du réseau est configurée de manière incohérente, tandis que le reste n'est pas affecté ou peut être rapidement basculé vers une nouvelle configuration.

Gérer le cycle de vie du programme eBPF pour les mises à jour

Le suivi du cycle de vie d'un programme eBPF est essentiel pour les programmes qui nécessitent de la persistance, des mises à jour fréquentes et la conservation de l'état sur différentes instances de code. Par exemple, si votre programme XDP nécessite des mises à jour fréquentes du code tout en conservant les sessions client existantes, il est essentiel de gérer efficacement son cycle de vie.

Pour les développeurs qui souhaitent maximiser la flexibilité et éviter les contraintes, l'objectif devrait être de conserver uniquement les informations importantes entre les rechargements, c'est-à-dire les données qui ne peuvent pas être récupérées à partir du stockage non volatile. De cette façon, vous pouvez utiliser les mappages eBPF pour les ajustements de configuration dynamiques.

Pour rendre le processus de rechargement à chaud du code plus simple, vous devez être capable de faire la distinction entre les cartes d'état et de configuration, de réutiliser la carte d'état pendant le rechargement et de repeupler la carte de configuration à partir d'un stockage non volatile. La transition du traitement de l'ancien programme vers le nouveau programme et la notification de tous les utilisateurs de cartographie eBPF des modifications peuvent s'avérer un peu fastidieuses.

Il existe deux manières courantes de mettre en œuvre des transitions :

  • Remplacement de programme atomique : Cette méthode consiste à attacher un programme XDP directement à une interface réseau et à l'échanger atomiquement lors d'une mise à jour. Ce n’est peut-être pas la solution la plus appropriée pour les programmes eBPF volumineux et complexes qui interagissent avec un grand nombre de programmes et de cartes de l’espace utilisateur.
  • Une approche de type libxdp : le programme planificateur se connecte à l'interface réseau et utilise des appels de fin pour effectuer le traitement dans le programme suivant dans la carte de programme où le traitement réel est effectué. En plus de gérer l'utilisation et l'épinglage de la carte, il coordonne plusieurs gestionnaires, permettant des transitions rapides entre eux.

Le diagramme montre la connexion de la carte d'interface réseau (NIC) au planificateur, à la carte du programme et à la carte d'état, ce qui donne lieu à la configuration réelle du programme.

La carte d'interface réseau (NIC) se connecte au planificateur, à la carte de programme et à la carte d'état, ce qui entraîne une configuration réelle du programme.

Le processus de rechargement à chaud détecte et corrige rapidement les problèmes de configuration et revient rapidement à une version stable précédente si nécessaire. Pour les scénarios complexes tels que les tests A/B, le planificateur peut utiliser des tables de classification pour diriger un trafic spécifique vers les nouvelles versions du programme XDP.

en conclusion

Grâce à la programmation eBPF/XDP, Gcore a repoussé les limites de la sécurité réseau et de l'optimisation des performances. Notre parcours démontre notre engagement à lutter contre les menaces émergentes grâce aux capacités avancées eBPF/XDP. Alors que nous continuons à améliorer notre noyau de traitement de paquets, nous nous engageons à fournir des solutions de pointe qui aident à maintenir les réseaux de nos clients robustes et agiles.

Cet article a été publié pour la première fois sur Yunyunzhongsheng ( https://yylives.cc/ ), tout le monde est invité à le visiter.

J'ai décidé d'abandonner l'open source Hongmeng Wang Chenglu, le père de l'open source Hongmeng : L'open source Hongmeng est le seul événement logiciel industriel d'innovation architecturale dans le domaine des logiciels de base en Chine - OGG 1.0 est publié, Huawei contribue à tout le code source. Google Reader est tué par la "montagne de merde de code" Ubuntu 24.04 LTS est officiellement publié Avant la sortie officielle de Fedora Linux 40, les développeurs Microsoft : les performances de Windows 11 sont "ridiculement mauvaises", Ma Huateng et Zhou Hongyi se serrent la main, "éliminant les rancunes" Des sociétés de jeux bien connues ont publié de nouvelles réglementations : les cadeaux de mariage des employés ne doivent pas dépasser 100 000 yuans. Pinduoduo a été condamné pour concurrence déloyale. Indemnisation de 5 millions de yuans.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/u/6919515/blog/11059370
conseillé
Classement