Surveillance du trafic eBPF

L'outil de trafic réseau eBPF utilise une combinaison d'implémentation de l'espace utilisateur et du noyau pour surveiller l'utilisation du réseau sur l'appareil depuis le dernier démarrage. Il offre des fonctionnalités supplémentaires telles que le balisage de sockets, la séparation du trafic au premier plan/en arrière-plan et un pare-feu par UID pour bloquer l'accès réseau des applications en fonction de l'état du téléphone. Les statistiques collectées à partir de l'outil sont stockées dans une structure de données du noyau appelée eBPF maps et le résultat est utilisé par des services tels que NetworkStatsService pour fournir des statistiques de trafic persistantes depuis le dernier démarrage.

Exemples et source

Les modifications de l'espace utilisateur se trouvent principalement dans les projets system/netd et framework/base. Le développement est effectué dans AOSP. Le code AOSP sera donc toujours à jour. La source se trouve principalement dans system/netd/server/TrafficController*, system/netd/bpfloader, et system/netd/libbpf/. Certaines modifications de framework nécessaires se trouvent également dans framework/base/ et system/core.

Implémentation

À partir d'Android 9, les appareils Android exécutés sur le noyau 4.9 ou version ultérieure et livrés à l'origine avec la version P DOIVENT utiliser la comptabilisation de la surveillance du trafic réseau basée sur eBPF au lieu de xt_qtaguid. La nouvelle infrastructure est plus flexible et plus facile à gérer, et ne nécessite aucun code de noyau hors de l'arborescence.

Les principales différences de conception entre la surveillance du trafic héritée et eBPF sont illustrées dans la figure 1.

Différences de conception entre l'ancien système de surveillance du trafic et eBPF

Figure 1. Différences de conception entre la surveillance du trafic héritée (à gauche) et eBPF (à droite)

La nouvelle conception trafficController est basée sur un filtre eBPF par cgroup, ainsi que sur le module netfilter xt_bpf dans le noyau. Ces filtres eBPF sont appliqués sur le paquet tx/rx lorsqu'ils passent par le filtre. Le filtre eBPF cgroup se trouve au niveau de la couche de transport et est chargé de comptabiliser le trafic par rapport à l'UID approprié en fonction de l'UID du socket et du paramètre de l'espace utilisateur. Le netfilter xt_bpf est associé aux chaînes bw_raw_PREROUTING et bw_mangle_POSTROUTING, et est chargé de comptabiliser le trafic par rapport à l'interface appropriée.

Au moment du démarrage, le processus de l'espace utilisateur trafficController crée les cartes eBPF utilisées pour la collecte de données et épingle toutes les cartes en tant que fichier virtuel dans sys/fs/bpf. Le processus privilégié bpfloader charge ensuite le programme eBPF précompilé dans le noyau et l'associe au cgroup approprié. Il existe un seul cgroup racine pour tout le trafic. Tous les processus doivent donc être inclus dans ce cgroup par défaut.

Au moment de l'exécution, trafficController peut baliser/supprimer le balisage d'un socket en écrivant dans traffic_cookie_tag_map et traffic_uid_counterSet_map. NetworkStatsService peut lire les données statistiques de trafic à partir de traffic_tag_stats_map, traffic_uid_stats_map et traffic_iface_stats_map. Outre la fonction de collecte des statistiques de trafic, le filtre eBPF trafficController et cgroup est également chargé de bloquer le trafic de certains UID en fonction des paramètres du téléphone. La fonctionnalité de blocage du trafic réseau basé sur l'UID remplace le module xt_owner dans le noyau. Le mode détaillé peut être configuré en écrivant dans traffic_powersave_uid_map, traffic_standby_uid_map et traffic_dozable_uid_map.

La nouvelle implémentation suit l'implémentation du module xt_qtaguid hérité. TrafficController et NetworkStatsService s'exécutent donc avec l'implémentation héritée ou la nouvelle. Si l'application utilise des API publiques, elle ne devrait pas constater de différence, que les outils xt_qtaguid ou eBPF soient utilisés en arrière-plan.

Si le noyau de l'appareil est basé sur le noyau commun Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 ou version ultérieure), aucune modification des HAL, des pilotes ou du code du noyau n'est requise pour implémenter le nouvel outil eBPF.

Conditions requises

  1. La configuration du noyau DOIT avoir les configurations suivantes activées :

    1. CONFIG_CGROUP_BPF=y
    2. CONFIG_BPF=y
    3. CONFIG_BPF_SYSCALL=y
    4. CONFIG_NETFILTER_XT_MATCH_BPF=y
    5. CONFIG_INET_UDP_DIAG=y

    Le test de configuration du noyau VTS est utile pour vérifier que la configuration correcte est activée.

Processus d'abandon de l'ancien xt_qtaguid

Le nouvel outil eBPF remplace le module xt_qtaguid et le module xt_owner sur lequel il est basé. Nous allons commencer à supprimer le module xt_qtaguid du noyau Android et à désactiver ses configurations inutiles.

Dans la version Android 9, le module xt_qtaguid est activé sur tous les appareils, mais toutes les API publiques qui lisent directement le fichier proc du module xt_qtaguid sont déplacées vers le service NetworkManagement. En fonction de la version du noyau de l'appareil et du premier niveau d'API, le service NetworkManagement sait si les outils eBPF sont activés et choisit le bon module à obtenir pour chaque statistique d'utilisation du réseau de l'application. Les applications dont le niveau de SDK est égal ou supérieur à 28 sont bloquées par sepolicy et ne peuvent pas accéder aux fichiers proc xt_qtaguid.

Dans la prochaine version d'Android après la version 9, l'accès des applications à ces fichiers proc xt_qtaguid sera complètement bloqué. Nous commencerons à supprimer le module xt_qtaguid des nouveaux noyaux communs Android. Une fois supprimé, nous mettrons à jour la configuration de base Android pour cette version du noyau afin de désactiver explicitement le module xt_qtaguid. Le module xt_qtaguid sera complètement obsolète lorsque la configuration minimale requise pour une version d'Android sera égale ou supérieure à 4.9.

Dans la version Android 9, seuls les appareils lancés avec la version Android 9 doivent disposer de la nouvelle fonctionnalité eBPF. Pour les appareils livrés avec un noyau compatible avec les outils eBPF, nous vous recommandons de le mettre à jour vers la nouvelle fonctionnalité eBPF lors de la mise à niveau vers la version Android 9. Aucun test CTS n'est disponible pour appliquer cette mise à jour.

Validation

Vous devez régulièrement appliquer des correctifs à partir des noyaux communs Android et de la branche principale d'Android AOSP. Assurez-vous que votre implémentation réussit les tests VTS et CTS applicables, netd_unit_test et libbpf_test.

Tests

Des tests net_tests du noyau permettent de s'assurer que les fonctionnalités requises sont activées et que les correctifs de noyau requis sont rétroportés. Les tests sont intégrés aux tests VTS de la version Android 9. Certains tests unitaires se trouvent dans system/netd/ (netd_unit_test et libbpf_test). Certains tests se trouvent dans netd_integration_test pour valider le comportement global du nouvel outil.

CTS et vérificateur CTS

Étant donné que les deux modules de surveillance du trafic sont compatibles avec la version Android 9, aucun test CTS n'est disponible pour forcer l'implémentation du nouveau module sur tous les appareils. Toutefois, pour les appareils dont la version de noyau est supérieure à 4.9 et qui sont livrés à l'origine avec la version Android 9 (c'est-à-dire le premier niveau d'API >= 28), des tests CTS sont disponibles sur GSI pour valider que le nouveau module est correctement configuré. Les anciens tests CTS tels que TrafficStatsTest, NetworkUsageStatsTest et CtsNativeNetTestCases peuvent être utilisés pour vérifier que le comportement est cohérent avec l'ancien module UID.

Tests manuels

Certains tests unitaires se trouvent dans system/netd/ (netd_unit_test, netd_integration_test et libbpf_test). La fonctionnalité dumpsys est disponible pour vérifier manuellement l'état. La commande dumpsys netd affiche l'état de base du module trafficController et indique si eBPF est correctement activé. Si eBPF est activé, la commande dumpsys netd trafficcontroller affiche le contenu détaillé de chaque carte eBPF, y compris les informations sur les sockets balisés, les statistiques par balise, UID et interface, ainsi que la correspondance de l'UID du propriétaire.

Emplacements des tests

Les tests CTS se trouvent à l'adresse suivante :

Les tests VTS se trouvent à l'adresse https://android.googlesource.com/kernel/tests/+/android17-release/net/test/bpf_test.py.

Les tests unitaires se trouvent à l'adresse suivante :