Pemantauan Lalu Lintas eBPF

Alat lalu lintas jaringan eBPF menggunakan kombinasi kernel dan implementasi ruang pengguna untuk memantau penggunaan jaringan pada perangkat sejak boot perangkat terakhir. Ini menyediakan fungsionalitas tambahan seperti penandaan soket, memisahkan lalu lintas latar depan/latar belakang dan firewall per-UID untuk memblokir aplikasi dari akses jaringan tergantung pada status ponsel. Statistik yang dikumpulkan dari alat disimpan dalam struktur data kernel yang disebut eBPF maps dan hasilnya digunakan oleh layanan seperti NetworkStatsService untuk menyediakan statistik lalu lintas persisten sejak boot terakhir.

Contoh dan sumber

Perubahan ruang pengguna terutama di proyek system/netd dan framework/base . Pengembangan sedang dilakukan di AOSP, sehingga kode AOSP akan selalu up to date. Sumber utamanya terletak di system/netd/server/TrafficController* , system/netd/bpfloader dan system/netd/libbpf/ . Beberapa perubahan kerangka kerja yang diperlukan ada di framework/base/ dan system/core juga.

Penerapan

Dimulai dengan Android 9, perangkat Android yang berjalan pada kernel 4.9 atau lebih tinggi dan awalnya dikirimkan dengan rilis P HARUS menggunakan akuntansi pemantauan lalu lintas jaringan berbasis eBPF, bukan xt_qtaguid . Infrastruktur baru ini lebih fleksibel dan lebih mudah dipelihara dan tidak memerlukan kode kernel yang tidak sesuai.

Perbedaan desain utama antara pemantauan lalu lintas lama dan eBPF diilustrasikan pada Gambar 1.

Perbedaan desain pemantauan lalu lintas lama dan eBPF

Gambar 1. Perbedaan desain pemantauan lalu lintas lama (kiri) dan eBPF (kanan)

Desain trafficController baru didasarkan pada filter cgroup per-cgroup serta modul netfilter xt_bpf di dalam kernel. Filter eBPF ini diterapkan pada paket tx/rx ketika melewati filter. cgroup eBPF terletak di lapisan transport dan bertanggung jawab untuk menghitung lalu lintas terhadap UID yang tepat tergantung pada UID soket serta pengaturan ruang pengguna. Netfilter xt_bpf terhubung pada rantai bw_raw_PREROUTING dan bw_mangle_POSTROUTING dan bertanggung jawab untuk menghitung lalu lintas terhadap antarmuka yang benar.

Saat boot, proses ruang pengguna trafficController membuat peta eBPF yang digunakan untuk pengumpulan data dan menyematkan semua peta sebagai file virtual di sys/fs/bpf . Kemudian bpfloader proses yang diistimewakan memuat program eBPF yang telah dikompilasi ke dalam kernel dan menempelkannya ke cgroup yang benar. Ada cgroup root tunggal untuk semua lalu lintas sehingga semua proses harus disertakan dalam cgroup itu secara default.

Saat dijalankan, trafficController dapat menandai/menghapus tanda soket dengan menulis ke traffic_cookie_tag_map dan traffic_uid_counterSet_map . NetworkStatsService dapat membaca data statistik lalu lintas dari traffic_tag_stats_map , traffic_uid_stats_map dan traffic_iface_stats_map . Selain fungsi pengumpulan statistik lalu lintas, trafficController dan cgroup eBPF juga bertanggung jawab untuk memblokir lalu lintas dari UID tertentu tergantung pada pengaturan telepon. Fitur pemblokiran lalu lintas jaringan berbasis UID adalah pengganti modul xt_owner di dalam kernel dan mode detail dapat dikonfigurasi dengan menulis ke traffic_powersave_uid_map , traffic_standby_uid_map dan traffic_dozable_uid_map .

Implementasi baru mengikuti implementasi modul xt_qtaguid lama sehingga TrafficController dan NetworkStatsService akan berjalan dengan implementasi lama atau baru. Jika aplikasi menggunakan API publik, seharusnya tidak ada perbedaan apakah alat xt_qtaguid atau eBPF digunakan di latar belakang.

Jika kernel perangkat didasarkan pada kernel umum Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 atau lebih tinggi), maka tidak diperlukan modifikasi pada HAL, driver, atau kode kernel untuk mengimplementasikan alat eBPF baru.

Persyaratan

  1. Konfigurasi kernel HARUS mengaktifkan konfigurasi berikut ini:

    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

    Tes konfigurasi kernel VTS berguna ketika memverifikasi konfigurasi yang benar telah diaktifkan.

  2. Perangkat MEM_LOCK HARUS disetel ke 8 MB atau lebih.

Proses penghentian xt_qtaguid lama

Alat eBPF baru menggantikan modul xt_qtaguid dan modul xt_owner yang menjadi dasarnya. Kami akan mulai menghapus modul xt_qtaguid dari kernel Android dan menonaktifkan konfigurasi yang tidak perlu.

Dalam rilis Android 9, modul xt_qtaguid diaktifkan di semua perangkat, tetapi semua API publik yang langsung membaca file proc modul xt_qtaguid dipindahkan ke Layanan NetworkManagement . Bergantung pada versi kernel perangkat dan level API pertama, Layanan NetworkManagement mengetahui apakah alat eBPF diaktifkan dan memilih modul yang tepat untuk mendapatkan setiap statistik penggunaan jaringan aplikasi. Aplikasi dengan SDK level 28 dan lebih tinggi diblokir dari mengakses file proc xt_qtaguid oleh sepolicy.

Dalam rilis Android berikutnya setelah 9, akses aplikasi ke file proc xt_qtaguid tersebut akan diblokir sepenuhnya. Kami akan mulai menghapus modul xt_qtaguid dari kernel umum Android yang baru. Setelah dihapus, kami akan memperbarui konfigurasi dasar Android untuk versi kernel tersebut untuk menonaktifkan modul xt_qtaguid secara eksplisit. Modul xt_qtaguid akan sepenuhnya dihentikan jika persyaratan versi kernel minimum untuk rilis Android adalah 4.9 atau lebih tinggi.

Dalam rilis Android 9, hanya perangkat yang diluncurkan dengan rilis Android 9 yang diharuskan memiliki fitur eBPF baru. Untuk perangkat yang dikirimkan dengan kernel yang dapat mendukung alat eBPF, sebaiknya perbarui ke fitur eBPF baru saat meningkatkan ke rilis Android 9. Tidak ada tes CTS untuk menerapkan pembaruan itu.

Validasi

Anda harus secara teratur mengambil patch dari kernel umum Android dan master AOSP Android. Pastikan implementasi Anda lulus uji VTS dan CTS yang berlaku, netd_unit_test , dan libbpf_test .

Pengujian

Ada kernel net_tests untuk memastikan Anda mengaktifkan fitur yang diperlukan dan patch kernel yang diperlukan di-backport. Pengujian tersebut terintegrasi sebagai bagian dari pengujian VTS rilis Android 9. Ada beberapa unit test di system/netd/ ( netd_unit_test dan libbpf_test ). Ada beberapa tes di netd_integration_test untuk memvalidasi perilaku keseluruhan alat baru.

Pemverifikasi CTS dan CTS

Karena kedua modul pemantauan lalu lintas didukung dalam rilis Android 9, tidak ada pengujian CTS untuk memaksa penerapan modul baru di semua perangkat. Namun untuk perangkat dengan versi kernel yang lebih tinggi dari 4.9 yang awalnya dikirimkan dengan rilis Android 9 (yaitu API level pertama >= 28), ada pengujian CTS pada GSI untuk memvalidasi modul baru yang dikonfigurasi dengan benar. Tes CTS lama seperti TrafficStatsTest , NetworkUsageStatsTest dan CtsNativeNetTestCases dapat digunakan untuk memverifikasi perilaku agar konsisten dengan modul UID lama.

Pengujian manual

Ada beberapa unit test di system/netd/ ( netd_unit_test , netd_integration_test dan libbpf_test ). Ada dukungan dumpsys untuk memeriksa status secara manual. Perintah dumpsys netd menunjukkan status dasar modul trafficController dan apakah eBPF diaktifkan dengan benar. Jika eBPF diaktifkan, perintah dumpsys netd trafficcontroller menampilkan konten terperinci dari setiap peta eBPF, termasuk informasi soket yang diberi tag, statistik per tag, UID dan iface, dan kecocokan UID pemilik.

Lokasi tes

Tes CTS berlokasi di:

Tes VTS terdapat di https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .

Tes unit berlokasi di: