Monitoraggio del traffico eBPF

Lo strumento per il traffico di rete eBPF utilizza una combinazione di kernel e implementazione dello spazio utente per monitorare l'utilizzo della rete sul dispositivo dall'ultimo avvio del dispositivo. Fornisce funzionalità aggiuntive come il tagging dei socket, la separazione del traffico in primo piano/in background e il firewall per-UID per bloccare le app dall'accesso alla rete a seconda dello stato del telefono. Le statistiche raccolte dallo strumento sono archiviate in una struttura dati del kernel chiamata eBPF maps e il risultato viene utilizzato da servizi come NetworkStatsService per fornire statistiche sul traffico persistenti dall'ultimo avvio.

Esempi e fonte

Le modifiche allo spazio utente sono principalmente nei progetti system/netd e framework/base . Lo sviluppo è in corso in AOSP, quindi il codice AOSP sarà sempre aggiornato. La fonte si trova principalmente in system/netd/server/TrafficController* , system/netd/bpfloader e system/netd/libbpf/ . Alcune modifiche al framework necessarie sono anche in framework/base/ e system/core .

Implementazione

A partire da Android 9, i dispositivi Android in esecuzione su kernel 4.9 o versioni successive e originariamente forniti con la versione P DEVONO utilizzare la contabilità di monitoraggio del traffico di rete basata su eBPF invece di xt_qtaguid . La nuova infrastruttura è più flessibile e manutenibile e non richiede alcun codice kernel fuori dall'albero.

Le principali differenze di progettazione tra il monitoraggio del traffico legacy ed eBPF sono illustrate nella Figura 1.

Differenze di progettazione del monitoraggio del traffico legacy ed eBPF

Figura 1. Differenze nella progettazione del monitoraggio del traffico legacy (a sinistra) ed eBPF (a destra).

Il nuovo design trafficController si basa sul filtro percgroup cgroup e sul modulo netfilter xt_bpf all'interno del kernel. Questi filtri eBPF vengono applicati al pacchetto tx/rx quando passano attraverso il filtro. Il filtro cgroup eBPF si trova a livello di trasporto ed è responsabile del conteggio del traffico rispetto all'UID corretto a seconda dell'UID del socket e dell'impostazione dello spazio utente. Il netfilter xt_bpf è agganciato alla catena bw_raw_PREROUTING e bw_mangle_POSTROUTING ed è responsabile del conteggio del traffico rispetto all'interfaccia corretta.

Al momento dell'avvio, il processo dello spazio utente trafficController crea le mappe eBPF utilizzate per la raccolta dei dati e blocca tutte le mappe come file virtuale in sys/fs/bpf . Quindi il processo privilegiato bpfloader carica il programma eBPF precompilato nel kernel e lo collega al cgroup corretto. Esiste un singolo cgroup radice per tutto il traffico, quindi tutto il processo dovrebbe essere incluso in quel cgroup per impostazione predefinita.

In fase di esecuzione, trafficController può taggare/staggare un socket scrivendo su traffic_cookie_tag_map e traffic_uid_counterSet_map . NetworkStatsService può leggere i dati delle statistiche sul traffico da traffic_tag_stats_map , traffic_uid_stats_map e traffic_iface_stats_map . Oltre alla funzione di raccolta delle statistiche sul traffico, il trafficController e il filtro eBPF di cgroup sono anche responsabili del blocco del traffico da determinati UID a seconda delle impostazioni del telefono. La funzione di blocco del traffico di rete basata su UID sostituisce il modulo xt_owner all'interno del kernel e la modalità di dettaglio può essere configurata scrivendo su traffic_powersave_uid_map , traffic_standby_uid_map e traffic_dozable_uid_map .

La nuova implementazione segue l'implementazione del modulo xt_qtaguid legacy, quindi TrafficController e NetworkStatsService verranno eseguiti con l'implementazione legacy o nuova. Se l'app utilizza API pubbliche, non dovrebbe verificarsi alcuna differenza se gli strumenti xt_qtaguid o eBPF vengono utilizzati in background.

Se il kernel del dispositivo è basato sul kernel comune Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 o superiore), non sono necessarie modifiche a HAL, driver o codice del kernel per implementare il nuovo strumento eBPF.

Requisiti

  1. La configurazione del kernel DEVE avere queste seguenti configurazioni attivate:

    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

    Il test di configurazione del kernel VTS è utile quando si verifica che la configurazione corretta sia attivata.

  2. Il dispositivo MEM_LOCK rlimit DEVE essere impostato su 8 MB o più.

Processo di ritiro di xt_qtaguid legacy

Il nuovo strumento eBPF sta sostituendo il modulo xt_qtaguid e il modulo xt_owner su cui si basa. Inizieremo a rimuovere il modulo xt_qtaguid dal kernel Android e a disabilitare le sue configurazioni non necessarie.

Nella versione Android 9, il modulo xt_qtaguid è attivato in tutti i dispositivi, ma tutte le API pubbliche che leggono direttamente il file proc del modulo xt_qtaguid vengono spostate nel servizio NetworkManagement . A seconda della versione del kernel del dispositivo e del primo livello API, il servizio NetworkManagement sa se gli strumenti eBPF sono attivati ​​e sceglie il modulo giusto da ottenere per ciascuna statistica sull'utilizzo della rete dell'app. Le app con SDK di livello 28 e superiori sono bloccate dall'accesso ai file proc xt_qtaguid da sepolicy.

Nella prossima versione di Android dopo il 9, l'accesso dell'app a quei file proc xt_qtaguid sarà completamente bloccato, inizieremo a rimuovere il modulo xt_qtaguid dai nuovi kernel comuni Android. Dopo che è stato rimosso, aggiorneremo la configurazione di base di Android per quella versione del kernel per disattivare esplicitamente il modulo xt_qtaguid . Il modulo xt_qtaguid sarà completamente deprecato quando il requisito minimo della versione del kernel per una versione Android è 4.9 o superiore.

Nella versione Android 9, solo i dispositivi che si avviano con la versione Android 9 devono disporre della nuova funzionalità eBPF. Per i dispositivi forniti con un kernel in grado di supportare gli strumenti eBPF, consigliamo di aggiornarlo alla nuova funzionalità eBPF durante l'aggiornamento alla versione di Android 9. Non esiste un test CTS per applicare tale aggiornamento.

Convalida

Dovresti prendere regolarmente patch dai kernel comuni Android e dal master AOSP Android. Assicurati che la tua implementazione superi i test VTS e CTS applicabili, netd_unit_test e libbpf_test .

Test

Esistono kernel net_tests per garantire che le funzionalità richieste siano attivate e le patch del kernel richieste siano state trasferite. I test sono integrati come parte dei test VTS della versione Android 9. Ci sono alcuni unit test in system/netd/ ( netd_unit_test e libbpf_test ). Ci sono alcuni test in netd_integration_test per convalidare il comportamento generale del nuovo strumento.

Verificatore CTS e CTS

Poiché entrambi i moduli di monitoraggio del traffico sono supportati nella versione Android 9, non esiste alcun test CTS per forzare l'implementazione del nuovo modulo su tutti i dispositivi. Ma per i dispositivi con versione del kernel superiore alla 4.9 che originariamente vengono forniti con la versione Android 9 (ovvero il primo livello API >= 28), ci sono test CTS su GSI per convalidare che il nuovo modulo sia configurato correttamente. I vecchi test CTS come TrafficStatsTest , NetworkUsageStatsTest e CtsNativeNetTestCases possono essere usati per verificare che il comportamento sia coerente con il vecchio modulo UID.

Test manuali

Ci sono alcuni unit test in system/netd/ ( netd_unit_test , netd_integration_test e libbpf_test ). C'è il supporto dumpsys per il controllo manuale dello stato. Il comando dumpsys netd mostra lo stato di base del modulo trafficController e se eBPF è attivato correttamente. Se eBPF è attivato, il comando dumpsys netd trafficcontroller mostra il contenuto dettagliato di ciascuna mappa eBPF, comprese le informazioni sui socket con tag, le statistiche per tag, UID e iface e la corrispondenza UID del proprietario.

Posizioni di prova

I test CTS si trovano presso:

I test VTS si trovano all'indirizzo https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .

I test unitari si trovano a: