giám sát lưu lượng eBPF

Công cụ lưu lượng mạng eBPF sử dụng kết hợp triển khai kernel và không gian người dùng để giám sát việc sử dụng mạng trên thiết bị kể từ lần khởi động thiết bị cuối cùng. Nó cung cấp chức năng bổ sung như gắn thẻ ổ cắm, phân tách lưu lượng nền trước/nền và tường lửa trên mỗi UID để chặn các ứng dụng truy cập mạng tùy thuộc vào trạng thái điện thoại. Số liệu thống kê được thu thập từ công cụ được lưu trữ trong cấu trúc dữ liệu hạt nhân được gọi là eBPF maps và kết quả được sử dụng bởi các dịch vụ như NetworkStatsService để cung cấp số liệu thống kê lưu lượng truy cập liên tục kể từ lần khởi động cuối cùng.

Ví dụ và nguồn

Những thay đổi về không gian người dùng chủ yếu diễn ra trong các dự án system/netdframework/base . Quá trình phát triển đang được thực hiện trong AOSP, vì vậy mã AOSP sẽ luôn được cập nhật. Nguồn chủ yếu nằm ở system/netd/server/TrafficController* , system/netd/bpfloadersystem/netd/libbpf/ . Một số thay đổi khung cần thiết cũng có trong framework/base/system/core .

Thực hiện

Bắt đầu với Android 9, các thiết bị Android chạy trên kernel 4.9 trở lên và ban đầu được cung cấp bản phát hành P PHẢI sử dụng tính năng tính toán giám sát lưu lượng mạng dựa trên eBPF thay vì xt_qtaguid . Cơ sở hạ tầng mới linh hoạt hơn, dễ bảo trì hơn và không yêu cầu bất kỳ mã hạt nhân ngoài cây nào.

Sự khác biệt chính về thiết kế giữa giám sát lưu lượng kế thừa và eBPF được minh họa trong Hình 1.

Sự khác biệt trong thiết kế giám sát lưu lượng kế thừa và eBPF

Hình 1. Sự khác biệt trong thiết kế giám sát lưu lượng truyền thống (trái) và eBPF (phải)

Thiết kế trafficController mới dựa trên bộ lọc eBPF theo cgroup cũng như mô-đun bộ lọc mạng xt_bpf bên trong kernel. Các bộ lọc eBPF này được áp dụng trên gói tx/rx khi chúng đi qua bộ lọc. Bộ lọc eBPF cgroup được đặt ở lớp vận chuyển và chịu trách nhiệm đếm lưu lượng truy cập theo đúng UID tùy thuộc vào UID ổ cắm cũng như cài đặt không gian người dùng. Bộ lọc mạng xt_bpf được nối vào chuỗi bw_raw_PREROUTINGbw_mangle_POSTROUTING và chịu trách nhiệm đếm lưu lượng truy cập theo giao diện chính xác.

Khi khởi động, quy trình không gian người dùng trafficController tạo bản đồ eBPF dùng để thu thập dữ liệu và ghim tất cả bản đồ dưới dạng tệp ảo tại sys/fs/bpf . Sau đó, quy trình đặc quyền bpfloader sẽ tải chương trình eBPF được biên dịch trước vào kernel và gắn nó vào đúng cgroup . Có một cgroup gốc duy nhất cho tất cả lưu lượng truy cập nên theo mặc định, tất cả quá trình phải được đưa vào cgroup đó.

Trong thời gian chạy, trafficController có thể gắn thẻ/bỏ gắn thẻ ổ cắm bằng cách ghi vào traffic_cookie_tag_maptraffic_uid_counterSet_map . NetworkStatsService có thể đọc dữ liệu thống kê lưu lượng truy cập từ traffic_tag_stats_map , traffic_uid_stats_maptraffic_iface_stats_map . Bên cạnh chức năng thu thập số liệu thống kê lưu lượng truy cập, bộ lọc trafficControllercgroup eBPF cũng chịu trách nhiệm chặn lưu lượng truy cập từ một số UID nhất định tùy thuộc vào cài đặt điện thoại. Tính năng chặn lưu lượng truy cập mạng dựa trên UID là sự thay thế mô-đun xt_owner bên trong kernel và chế độ chi tiết có thể được định cấu hình bằng cách ghi vào traffic_powersave_uid_map , traffic_standby_uid_maptraffic_dozable_uid_map .

Việc triển khai mới tuân theo cách triển khai mô-đun xt_qtaguid cũ nên TrafficControllerNetworkStatsService sẽ chạy với cách triển khai cũ hoặc mới. Nếu ứng dụng sử dụng API công khai thì ứng dụng sẽ không gặp bất kỳ sự khác biệt nào cho dù sử dụng công cụ xt_qtaguid hay eBPF ở chế độ nền.

Nếu nhân của thiết bị dựa trên nhân phổ biến của Android 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 trở lên), thì không cần sửa đổi HAL, trình điều khiển hoặc mã nhân để triển khai công cụ eBPF mới.

Yêu cầu

  1. Cấu hình kernel PHẢI bật các cấu hình sau:

    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

    Kiểm tra cấu hình kernel VTS rất hữu ích khi xác minh đã bật cấu hình chính xác.

Quá trình ngừng sử dụng xt_qtaguid kế thừa

Công cụ eBPF mới đang thay thế mô-đun xt_qtaguid và mô-đun xt_owner mà nó dựa trên. Chúng tôi sẽ bắt đầu xóa mô-đun xt_qtaguid khỏi nhân Android và tắt các cấu hình không cần thiết của nó.

Trong bản phát hành Android 9, mô-đun xt_qtaguid được bật trên tất cả các thiết bị, nhưng tất cả các API công khai đọc trực tiếp tệp Proc mô-đun xt_qtaguid đều được chuyển vào Dịch vụ NetworkManagement . Tùy thuộc vào phiên bản kernel của thiết bị và cấp API đầu tiên, Dịch vụ NetworkManagement sẽ biết liệu công cụ eBPF có được bật hay không và chọn mô-đun phù hợp để nhận chỉ số sử dụng mạng cho từng ứng dụng. Các ứng dụng có SDK cấp 28 trở lên bị chặn truy cập vào các tệp Proc xt_qtaguid theo chính sách riêng biệt.

Trong bản phát hành Android tiếp theo sau ngày 9, quyền truy cập của ứng dụng vào các tệp Proc xt_qtaguid đó sẽ bị chặn hoàn toàn. Chúng tôi sẽ bắt đầu xóa mô-đun xt_qtaguid khỏi các nhân phổ biến mới của Android. Sau khi xóa nó, chúng tôi sẽ cập nhật cấu hình cơ sở Android cho phiên bản kernel đó để tắt mô-đun xt_qtaguid một cách rõ ràng. Mô-đun xt_qtaguid sẽ hoàn toàn không được dùng nữa khi yêu cầu phiên bản kernel tối thiểu cho bản phát hành Android là 4.9 trở lên.

Trong bản phát hành Android 9, chỉ những thiết bị khởi chạy cùng bản phát hành Android 9 mới phải có tính năng eBPF mới. Đối với các thiết bị đi kèm hạt nhân có thể hỗ trợ các công cụ eBPF, chúng tôi khuyên bạn nên cập nhật hạt nhân đó lên tính năng eBPF mới khi nâng cấp lên bản phát hành Android 9. Không có bài kiểm tra CTS nào để thực thi bản cập nhật đó.

Thẩm định

Bạn nên thường xuyên lấy các bản vá từ kernel phổ biến của Android và Android AOSP chính. Đảm bảo việc triển khai của bạn vượt qua các bài kiểm tra VTS và CTS hiện hành, netd_unit_testlibbpf_test .

Kiểm tra

kernel net_tests để đảm bảo bạn đã bật các tính năng cần thiết và các bản vá kernel bắt buộc được nhập ngược. Các thử nghiệm được tích hợp như một phần của thử nghiệm VTS phát hành Android 9. Có một số bài kiểm tra đơn vị trong system/netd/ ( netd_unit_testlibbpf_test ). Có một số thử nghiệm trong netd_integration_test để xác thực hoạt động tổng thể của công cụ mới.

Trình xác minh CTS và CTS

Vì cả hai mô-đun giám sát lưu lượng truy cập đều được hỗ trợ trong bản phát hành Android 9 nên không có thử nghiệm CTS nào để buộc triển khai mô-đun mới trên tất cả các thiết bị. Nhưng đối với các thiết bị có phiên bản kernel cao hơn 4.9 đi kèm với bản phát hành Android 9 ban đầu (tức là cấp API đầu tiên >= 28), sẽ có các bài kiểm tra CTS trên GSI để xác thực mô-đun mới được định cấu hình chính xác. Các thử nghiệm CTS cũ như TrafficStatsTest , NetworkUsageStatsTestCtsNativeNetTestCases có thể được sử dụng để xác minh hành vi có nhất quán với mô-đun UID cũ hay không.

Kiểm tra bằng tay

Có một số bài kiểm tra đơn vị trong system/netd/ ( netd_unit_test , netd_integration_testlibbpf_test ). Có hỗ trợ dumpsys để kiểm tra trạng thái theo cách thủ công. Lệnh dumpsys netd hiển thị trạng thái cơ bản của mô-đun trafficController và liệu eBPF có được bật chính xác hay không. Nếu eBPF được bật, lệnh dumpsys netd trafficcontroller sẽ hiển thị nội dung chi tiết của từng bản đồ eBPF, bao gồm thông tin ổ cắm được gắn thẻ, số liệu thống kê trên mỗi thẻ, UID và iface cũng như kết quả trùng khớp UID của chủ sở hữu.

Địa điểm kiểm tra

Các bài kiểm tra CTS được đặt tại:

Các bài kiểm tra VTS được đặt tại https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py .

Các bài kiểm tra đơn vị được đặt tại: