eBPF 트래픽 모니터링

eBPF 네트워크 트래픽 도구는 커널과 사용자 공간 구현의 조합을 이용하여 기기의 마지막 부팅 이후의 네트워크 사용량을 모니터링합니다. 이 도구는 휴대전화 상태에 따라 네트워크 액세스에서 앱을 차단하기 위해 소켓 태그하기, 포그라운드/백그라운드 트래픽 분리, UID별 방화벽과 같은 추가 기능을 제공합니다. 도구에서 수집한 통계는 eBPF maps라는 커널 데이터 구조에 저장되며 결과는 NetworkStatsService와 같은 서비스에서 마지막 부팅 이후에 발생하는 트래픽 통계를 지속적으로 제공하는 데 사용됩니다.

예시 및 소스

사용자 공간 변경사항은 주로 system/netdframework/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에 나와 있습니다.

기존 및 eBPF 트래픽 모니터링의 디자인 차이점

그림 1. 기존(왼쪽) 및 eBPF(오른쪽) 트래픽 모니터링의 디자인 차이점

새로운 trafficController 디자인은 cgroup당 eBPF 필터뿐 아니라 커널 내부의 xt_bpf 넷필터 모듈에 기반합니다. 이러한 eBPF 필터는 필터를 통과할 때 패킷 tx/rx에 적용됩니다. cgroup eBPF 필터는 전송 레이어에 있으며 소켓 UID뿐 아니라 사용자 공간 설정에 따라 올바른 UID와 비교하여 트래픽을 계산합니다. xt_bpf 넷필터는 bw_raw_PREROUTINGbw_mangle_POSTROUTING 체인에 연결되며 올바른 인터페이스와 비교하여 트래픽을 계산합니다.

부팅 시 사용자 공간 프로세스 trafficController는 데이터 수집에 사용되는 eBPF 맵을 만들고 모든 맵을 sys/fs/bpf에서 가상 파일로 고정합니다. 그런 다음 권한이 있는 프로세스 bpfloader는 사전 컴파일된 eBPF 프로그램을 커널에 로드하고 올바른 cgroup에 연결합니다. 모든 트래픽에 단일 루트 cgroup이 있으므로 기본적으로 모든 프로세스가 그 cgroup에 포함되어야 합니다.

런타임 시 trafficControllertraffic_cookie_tag_maptraffic_uid_counterSet_map에 작성하여 소켓에 태그하거나 태그 취소할 수 있습니다. NetworkStatsServicetraffic_tag_stats_map, traffic_uid_stats_maptraffic_iface_stats_map에서 트래픽 통계 데이터를 읽을 수 있습니다. 트래픽 통계 수집 기능 외에도 trafficControllercgroup eBPF 필터는 휴대전화 설정에 따라 특정 UID의 트래픽을 차단합니다. UID 기반 네트워킹 트래픽 차단 기능은 커널 내부의 xt_owner 모듈을 대체하며 세부 모드는 traffic_powersave_uid_map, traffic_standby_uid_maptraffic_dozable_uid_map에 작성하여 구성할 수 있습니다.

새 구현은 기존 xt_qtaguid 모듈 구현을 따르므로 TrafficControllerNetworkStatsService는 기존 구현 또는 새 구현과 함께 실행됩니다. 앱이 공개 API를 사용하는 경우 xt_qtaguid 또는 eBPF 도구가 백그라운드에서 사용되더라도 차이가 없어야 합니다.

기기 커널이 Android 일반 커널 4.9(SHA 39c856663dcc81739e52b02b77d6af259eb838f6 이상)를 기반으로 하는 경우 새 eBPF 도구를 구현하기 위해 HAL, 드라이버 또는 커널 코드를 수정하지 않아도 됩니다.

요구사항

  1. 커널 구성에는 다음 구성이 사용 설정되어 있어야 합니다.

    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

    VTS 커널 구성 테스트는 올바른 구성이 사용 설정되어 있는지 확인할 때 유용합니다.

기존 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 main에서 패치를 가져와야 합니다. 구현이 관련 VTS 및 CTS 테스트, netd_unit_test, libbpf_test를 통과하는지 확인합니다.

테스트

커널 net_tests를 사용하여 필수 기능이 사용 설정되어 있고 필수 커널 패치가 백포트되어 있는지 확인합니다. 이 테스트는 Android 9 버전 VTS 테스트의 일부로 통합되었습니다. system/netd/에는 단위 테스트(netd_unit_testlibbpf_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 netdtrafficController 모듈의 기본 상태와 eBPF가 올바르게 사용 설정되어 있는지 표시합니다. eBPF가 사용 설정되어 있으면 명령어 dumpsys netd trafficcontroller는 태그된 소켓 정보, 태그당 통계, UID 및 iface, 소유자 UID 일치를 비롯하여 각 eBPF 맵의 자세한 콘텐츠를 표시합니다.

테스트 위치

CTS 테스트는 다음 위치에 있습니다.

VTS 테스트는 https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py에 있습니다.

단위 테스트는 다음 위치에 있습니다.