eBPF 네트워크 트래픽 도구는 커널과 사용자 공간 구현의 조합을 이용하여 기기의 마지막 부팅 이후의 네트워크 사용량을 모니터링합니다. 이 도구는 휴대전화 상태에 따라 네트워크 액세스에서 앱을 차단하기 위해 소켓 태그하기, 포그라운드/백그라운드 트래픽 분리, UID별 방화벽과 같은 추가 기능을 제공합니다. 도구에서 수집한 통계는 eBPF maps
라는 커널 데이터 구조에 저장되며 결과는 NetworkStatsService
와 같은 서비스에서 마지막 부팅 이후에 발생하는 트래픽 통계를 지속적으로 제공하는 데 사용됩니다.
예시 및 소스
사용자 공간 변경사항은 주로 system/netd
및 framework/base
프로젝트에 있습니다. AOSP에서 개발이 진행되므로 AOSP 코드는 항상 최신 상태입니다. 소스는 주로 system/netd/server/TrafficController*
, system/netd/bpfloader
및 system/netd/libbpf/
에 있습니다.
일부 필요한 프레임워크 변경사항은 framework/base/
및 system/core
에도 있습니다.
구현
Android 9부터 커널 4.9 이상에서 실행되고 원래 P 버전과 함께 제공된 Android 기기는 xt_qtaguid
대신 eBPF 기반 네트워크 트래픽 모니터링 계정을 사용해야 합니다. 새로운 인프라는 더 유연하고 유지관리가 쉬우며 트리 외부 커널 코드가 필요하지 않습니다.
기존 및 eBPF 트래픽 모니터링 간의 주요 디자인 차이점은 그림 1에 나와 있습니다.
그림 1. 기존(왼쪽) 및 eBPF(오른쪽) 트래픽 모니터링의 디자인 차이점
새로운 trafficController
디자인은 cgroup
당 eBPF 필터뿐 아니라 커널 내부의 xt_bpf
넷필터 모듈에 기반합니다. 이러한 eBPF 필터는 필터를 통과할 때 패킷 tx/rx에 적용됩니다. cgroup
eBPF 필터는 전송 레이어에 있으며 소켓 UID뿐 아니라 사용자 공간 설정에 따라 올바른 UID와 비교하여 트래픽을 계산합니다.
xt_bpf
넷필터는 bw_raw_PREROUTING
및 bw_mangle_POSTROUTING
체인에 연결되며 올바른 인터페이스와 비교하여 트래픽을 계산합니다.
부팅 시 사용자 공간 프로세스 trafficController
는 데이터 수집에 사용되는 eBPF 맵을 만들고 모든 맵을 sys/fs/bpf
에서 가상 파일로 고정합니다.
그런 다음 권한이 있는 프로세스 bpfloader
는 사전 컴파일된 eBPF 프로그램을 커널에 로드하고 올바른 cgroup
에 연결합니다. 모든 트래픽에 단일 루트 cgroup
이 있으므로 기본적으로 모든 프로세스가 그 cgroup
에 포함되어야 합니다.
런타임 시 trafficController
는 traffic_cookie_tag_map
및 traffic_uid_counterSet_map
에 작성하여 소켓에 태그하거나 태그 취소할 수 있습니다. NetworkStatsService
는 traffic_tag_stats_map
, traffic_uid_stats_map
및 traffic_iface_stats_map
에서 트래픽 통계 데이터를 읽을 수 있습니다.
트래픽 통계 수집 기능 외에도 trafficController
및 cgroup
eBPF 필터는 휴대전화 설정에 따라 특정 UID의 트래픽을 차단합니다. UID 기반 네트워킹 트래픽 차단 기능은 커널 내부의 xt_owner
모듈을 대체하며 세부 모드는 traffic_powersave_uid_map
, traffic_standby_uid_map
및 traffic_dozable_uid_map
에 작성하여 구성할 수 있습니다.
새 구현은 기존 xt_qtaguid
모듈 구현을 따르므로 TrafficController
및 NetworkStatsService
는 기존 구현 또는 새 구현과 함께 실행됩니다. 앱이 공개 API를 사용하는 경우 xt_qtaguid
또는 eBPF 도구가 백그라운드에서 사용되더라도 차이가 없어야 합니다.
기기 커널이 Android 일반 커널 4.9(SHA 39c856663dcc81739e52b02b77d6af259eb838f6 이상)를 기반으로 하는 경우 새 eBPF 도구를 구현하기 위해 HAL, 드라이버 또는 커널 코드를 수정하지 않아도 됩니다.
요구사항
커널 구성에는 다음 구성이 사용 설정되어 있어야 합니다.
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_INET_UDP_DIAG=y
VTS 커널 구성 테스트는 올바른 구성이 사용 설정되어 있는지 확인할 때 유용합니다.
MEM_LOCK
rlimit 기기는 8MB 이상으로 설정되어야 합니다.
기존 xt_qtaguid 지원 중단 프로세스
새 eBPF 도구는 기반을 두고 있는 xt_qtaguid
모듈과 xt_owner
모듈을 대체합니다. Android 커널에서 xt_qtaguid
모듈을 삭제하고 불필요한 구성을 사용 중지할 예정입니다.
Android 9 버전에서는 xt_qtaguid
모듈이 모든 기기에 사용 설정되어 있지만 xt_qtaguid
모듈 proc 파일을 직접 읽는 모든 공개 API는 NetworkManagement
서비스로 이동됩니다.
기기 커널 버전과 첫 번째 API 수준에 따라 NetworkManagement
서비스는 eBPF 도구가 사용 설정되어 있는지 확인하고 각 앱 네트워크 사용 통계를 위해 가져올 올바른 모듈을 선택합니다. SDK 수준 28 이상을 사용하는 앱은 sepolicy를 통해 xt_qtaguid
proc 파일 액세스에서 차단됩니다.
Android 9 이후의 버전에서는 이러한 xt_qtaguid
proc 파일의 앱 액세스가 완전히 차단되며 새 Android 일반 커널에서 xt_qtaguid
모듈이 삭제됩니다. 삭제된 후에는 커널 버전의 Android 기본 구성을 업데이트하여 명시적으로 xt_qtaguid
모듈을 사용 중지합니다. xt_qtaguid
모듈은 Android 버전의 최소 커널 버전 요구사항이 4.9 이상이면 완전히 지원 중단됩니다.
Android 9 버전에서는 Android 9 버전과 함께 출시되는 기기에만 새 eBPF 기능이 요구됩니다. eBPF 도구를 지원할 수 있는 커널이 함께 제공된 기기의 경우 Android 9 버전으로 업그레이드할 때 새 eBPF 기능으로 업데이트하는 것이 좋습니다. 업데이트를 적용할 CTS 테스트는 없습니다.
유효성 검사
정기적으로 Android 일반 커널과 Android AOSP 마스터에서 패치를 가져와야 합니다. 구현이 관련 VTS 및 CTS 테스트, netd_unit_test
, libbpf_test
를 통과하는지 확인합니다.
테스트
커널 net_tests를 사용하여 필수 기능이 사용 설정되어 있고 필수 커널 패치가 백포트되어 있는지 확인합니다. 이 테스트는 Android 9 버전 VTS 테스트의 일부로 통합되었습니다. system/netd/
에는 단위 테스트(netd_unit_test
및 libbpf_test
)가 있습니다. netd_integration_test
에는 새 도구의 전체 동작을 검증하는 테스트가 있습니다.
CTS 및 CTS 인증 도구
트래픽 모니터링 모듈은 둘 다 Android 9 버전에서 지원되므로 CTS 테스트 없이 모든 기기에 새 모듈을 구현할 수 있습니다. 하지만 원래 Android 9 버전과 함께 제공되어 커널 버전이 4.9 이상인 기기의 경우(첫 API 수준이 28 이상) 새 모듈이 올바르게 구성되었는지 검증하는 GSI의 CTS 테스트가 있습니다. TrafficStatsTest
, NetworkUsageStatsTest
, CtsNativeNetTestCases
와 같은 이전 CTS 테스트를 사용하여 동작이 이전 UID 모듈과 일관되는지 확인할 수 있습니다.
수동 테스트
system/netd/
에는 단위 테스트(netd_unit_test
, netd_integration_test
, libbpf_test
)가 있습니다. dumpsys 지원으로 상태를 수동으로 확인할 수 있습니다. 명령어 dumpsys netd
는 trafficController
모듈의 기본 상태와 eBPF가 올바르게 사용 설정되어 있는지 표시합니다. eBPF가 사용 설정되어 있으면 명령어 dumpsys netd trafficcontroller
는 태그된 소켓 정보, 태그당 통계, UID 및 iface, 소유자 UID 일치를 비롯하여 각 eBPF 맵의 자세한 콘텐츠를 표시합니다.
위치 테스트
CTS 테스트는 다음 위치에 있습니다.
- https://android.googlesource.com/platform/cts/+/master/tests/tests/net/src/android/net/cts/TrafficStatsTest.java{: .external}
- https://android.googlesource.com/platform/cts/+/master/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java{: .external}
- https://android.googlesource.com/platform/system/netd/+/master/tests/bpf_base_test.cpp{: .external}
VTS 테스트는 https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py에 있습니다.
단위 테스트는 다음 위치에 있습니다.
- https://android.googlesource.com/platform/system/netd/+/master/libbpf/BpfNetworkStatsTest.cpp{: .external}
- https://android.googlesource.com/platform/system/netd/+/master/server/TrafficControllerTest.cpp{: .external}