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 대신 xt_qtaguid
기반 네트워크 트래픽 모니터링 계정을 사용해야 합니다(MUST). 새로운 인프라는 더 유연하고 유지 관리가 용이하며 트리 외부 커널 코드가 필요하지 않습니다.
레거시 트래픽 모니터링과 eBPF 트래픽 모니터링 간의 주요 설계 차이점은 그림 1에 나와 있습니다.
그림 1. 기존(왼쪽) 및 eBPF(오른쪽) 트래픽 모니터링 설계 차이점
새로운 trafficController
디자인은 per- cgroup
eBPF 필터와 커널 내부의 xt_bpf
netfilter 모듈을 기반으로 합니다. 이러한 eBPF 필터는 필터를 통과할 때 패킷 tx/rx에 적용됩니다. cgroup
eBPF 필터는 전송 계층에 있으며 소켓 UID 및 사용자 공간 설정에 따라 올바른 UID에 대한 트래픽 계산을 담당합니다. xt_bpf
netfilter는 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 이상)를 기반으로 하는 경우 HAL, 드라이버 또는 커널 코드를 수정하여 새 eBPF 도구를 구현하지 않아도 됩니다.
요구 사항
커널 구성에는 다음 구성이 켜져 있어야 합니다.
-
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 이상으로 설정해야 합니다(MUST).
레거시 xt_qtaguid 지원 중단 프로세스
새로운 eBPF 도구는 xt_qtaguid
모듈과 이 도구가 기반으로 하는 xt_owner
모듈을 대체합니다. Android 커널에서 xt_qtaguid
모듈을 제거하고 불필요한 구성을 비활성화하기 시작합니다.
Android 9 릴리스에서는 xt_qtaguid
모듈이 모든 기기에서 켜져 있지만 xt_qtaguid
모듈 proc 파일을 직접 읽는 모든 공개 API는 NetworkManagement
서비스로 이동됩니다. 장치 커널 버전 및 첫 번째 API 수준에 따라 NetworkManagement
Service는 eBPF 도구가 켜져 있는지 여부를 알고 각 앱 네트워크 사용 통계에 대해 가져올 올바른 모듈을 선택합니다. SDK 레벨 28 이상의 앱은 sepolicy에 의해 xt_qtaguid
proc 파일에 액세스하는 것이 차단됩니다.
9 이후의 다음 Android 릴리스에서는 해당 xt_qtaguid
proc 파일에 대한 앱 액세스가 완전히 차단됩니다. 새로운 Android 공통 커널에서 xt_qtaguid
모듈을 제거하기 시작할 것입니다. 제거된 후 xt_qtaguid
모듈을 명시적으로 끄도록 해당 커널 버전에 대한 Android 기본 구성을 업데이트합니다. 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 릴리스(즉, 첫 번째 API 레벨 >= 28)와 함께 제공되는 커널 버전이 4.9 이상인 기기의 경우 새 모듈이 올바르게 구성되었는지 확인하기 위한 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}