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 việc triển khai nhân 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 truy cập nền / 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ê thu thập được từ công cụ được lưu trữ trong cấu trúc dữ liệu hạt nhân 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 thống kê lưu lượng 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 là 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 được đặt tại system/netd/server/TrafficController* , system/netd/bpfloadersystem/netd/libbpf/ . Một số thay đổi khung cần thiết cũng nằm trong framework/base/ và cả system/core .

Thực hiện

Bắt đầu với Android 9, các thiết bị Android chạy trên nhân 4.9 trở lên và ban đầu được xuất xưởng với bản phát hành P PHẢI sử dụ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 và dễ bảo trì hơn và không yêu cầu bất kỳ mã 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 về thiết kế giám sát lưu lượng eBPF và kế thừa

Hình 1. Sự khác biệt về thiết kế giám sát giao thông kế thừa (trái) và eBPF (phải)

Thiết kế trafficController mới dựa trên bộ lọc eBPF per- cgroup cũng như mô-đun netfilter xt_bpf bên trong hạt nhân. 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 cgroup cgroup nằm ở lớp truyền tải và chịu trách nhiệm đếm lưu lượng truy cập vào đúng UID tùy thuộc vào UID ổ cắm cũng như cài đặt không gian người dùng. xt_bpf được nối với chuỗi bw_raw_PREROUTINGbw_mangle_POSTROUTING và chịu trách nhiệm đếm lưu lượng truy cập vào đúng giao diện.

Tại thời điểm khởi động, không gian người dùng xử lý trafficController tạo các bản đồ eBPF được sử dụng để thu thập dữ liệu và ghim tất cả các bản đồ dưới dạng tệp ảo tại sys/fs/bpf . Sau đó, tiến trình đặc quyền bpfloader tải chương trình eBPF được biên dịch trước vào hạt nhân 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, do đó, tất cả quá trình phải được bao gồm trong cgroup đó theo mặc định.

Tại thời điểm chạy, trafficController có thể gắn thẻ / bỏ gắn thẻ một ổ 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 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, bộ lọc eBPF trafficControllercgroup còn có nhiệm vụ 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 hạt nhân 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 triển khai mô-đun xt_qtaguid kế thừa để TrafficControllerNetworkStatsService sẽ chạy với triển khai cũ hoặc mới. Nếu ứng dụng sử dụng các API công khai, ứng dụng sẽ không gặp bất kỳ sự khác biệt nào cho dù các công cụ xt_qtaguid hay eBPF được sử dụng trong 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 hạt nhân 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 hạt nhân VTS rất hữu ích khi xác minh cấu hình chính xác được bật.

  2. Thiết bị MEM_LOCK rlimit PHẢI được đặt thành 8 MB trở lên.

Quy 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 sẽ được chuyển vào Dịch vụ Quản lý NetworkManagement . Tùy thuộc vào phiên bản hạt nhân của thiết bị và cấp API đầu tiên, Dịch vụ quản lý mạng biết liệu các công cụ NetworkManagement có được bật hay không và chọn mô-đun phù hợp để tải cho từng chỉ số sử dụng mạng ứng dụng. Các ứng dụng có SDK cấp 28 trở lên bị xt_qtaguid chặn truy cập vào các tệp proc xt_qtaguid.

Trong bản phát hành Android tiếp theo sau 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 thông dụng mới của Android. Sau khi nó bị xóa, chúng tôi sẽ cập nhật cấu hình cơ sở Android cho phiên bản hạt nhân đó để 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 hạt nhân 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 với bản phát hành Android 9 mới được yêu cầu có tính năng eBPF mới. Đối với các thiết bị được vận chuyển với nhân có thể hỗ trợ công cụ eBPF, chúng tôi khuyên bạn nên cập nhậ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 nhận các bản vá từ các hạt nhân 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 .

Thử nghiệm

Có các net_tests hạt nhân để đảm bảo bạn đã bật các tính năng cần thiết và các bản vá lỗi hạt nhân bắt buộc phải được báo cáo lại. Các bài kiểm tra được tích hợp như một phần của bài kiểm tra VTS phiên bản 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 hành vi tổng thể của công cụ mới.

CTS và trình xác minh CTS

Vì cả hai mô-đun giám sát lưu lượng đều được hỗ trợ trong bản phát hành Android 9, không có bài kiểm tra 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 hạt nhân cao hơn 4.9 mà ban đầu xuất xưởng với bản phát hành Android 9 (tức là cấp API đầu tiên> = 28), có các bài kiểm tra CTS trên GSI để xác nhận mô-đun mới được định cấu hình chính xác. Các bài kiểm tra CTS cũ như TrafficStatsTest , NetworkUsageStatsTestCtsNativeNetTestCases có thể được sử dụng để xác minh hành vi phù hợp với mô-đun UID cũ.

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ợ bãi chứa để 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 đúng cách hay không. Nếu eBPF được bật, lệnh kết xuất bộ điều khiển dumpsys netd trafficcontroller 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ê cho mỗi thẻ, UID và iface và kết quả phù hợp với UID của chủ sở hữu.

Địa điểm thử nghiệm

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

Các bài kiểm tra VTS có tại https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .

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