eBPF ट्रैफ़िक मॉनिटरिंग

eBPF नेटवर्क ट्रैफ़िक टूल, कर्नेल और उपयोगकर्ता स्पेस के कॉम्बिनेशन का इस्तेमाल करता है. इससे, डिवाइस के आखिरी बूट के बाद से, डिवाइस पर नेटवर्क के इस्तेमाल को मॉनिटर किया जा सकता है. यह सॉकेट टैगिंग, फ़ोरग्राउंड/बैकग्राउंड ट्रैफ़िक को अलग करने, और फ़ोन की स्थिति के आधार पर ऐप्लिकेशन को नेटवर्क ऐक्सेस करने से रोकने के लिए, यूआईडी के हिसाब से फ़ायरवॉल जैसी अतिरिक्त सुविधाएं देता है. इस टूल से इकट्ठा किए गए आंकड़े, कर्नल डेटा स्ट्रक्चर में सेव किए जाते हैं. इसे 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 या इसके बाद के वर्शन पर काम करने वाले Android डिवाइसों के लिए, xt_qtaguid के बजाय eBPF पर आधारित नेटवर्क ट्रैफ़िक मॉनिटरिंग का इस्तेमाल करना ज़रूरी है. साथ ही, यह भी ज़रूरी है कि ये डिवाइस, P रिलीज़ के साथ शिप किए गए हों. नया इन्फ़्रास्ट्रक्चर ज़्यादा बेहतर है और इसे आसानी से मैनेज किया जा सकता है. इसके लिए, किसी भी आउट-ऑफ़-ट्री कर्नल कोड की ज़रूरत नहीं होती.

लेगसी और eBPF ट्रैफ़िक मॉनिटरिंग के बीच डिज़ाइन से जुड़े मुख्य अंतर, इमेज 1 में दिखाए गए हैं.

लेगसी और eBPF ट्रैफ़िक मॉनिटरिंग के डिज़ाइन में अंतर

पहली इमेज. लेगसी (बाएं) और eBPF (दाएं) ट्रैफ़िक मॉनिटरिंग डिज़ाइन के बीच अंतर

नया trafficController डिज़ाइन, हर cgroup eBPF फ़िल्टर के साथ-साथ कर्नल के अंदर मौजूद xt_bpf netfilter मॉड्यूल पर भी आधारित है. ये eBPF फ़िल्टर, पैकेट tx/rx पर लागू होते हैं. ऐसा तब होता है, जब वे फ़िल्टर से गुज़रते हैं. cgroup eBPF फ़िल्टर ट्रांसपोर्ट लेयर पर मौजूद होता है. यह सॉकेट यूआईडी और यूज़रस्पेस सेटिंग के आधार पर, सही यूआईडी के लिए ट्रैफ़िक को गिनने का काम करता है. xt_bpf netfilter, bw_raw_PREROUTING और bw_mangle_POSTROUTING चेन से जुड़ा होता है. साथ ही, यह सही इंटरफ़ेस के हिसाब से ट्रैफ़िक को गिनने के लिए ज़िम्मेदार होता है.

बूट होने के समय, userspace प्रोसेस 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 फ़िल्टर भी कुछ यूआईडी से ट्रैफ़िक को ब्लॉक करने के लिए ज़िम्मेदार होते हैं. यह फ़ोन की सेटिंग पर निर्भर करता है. यूआईडी के आधार पर नेटवर्क ट्रैफ़िक को ब्लॉक करने की सुविधा, कर्नल में मौजूद xt_owner मॉड्यूल की जगह इस्तेमाल की जाती है. साथ ही, ज़्यादा जानकारी वाले मोड को traffic_powersave_uid_map, traffic_standby_uid_map, और traffic_dozable_uid_map में लिखकर कॉन्फ़िगर किया जा सकता है.

नया वर्शन, लेगसी xt_qtaguid मॉड्यूल के साथ काम करता है. इसलिए, TrafficController और NetworkStatsService, लेगसी या नए वर्शन के साथ काम करेंगे. अगर ऐप्लिकेशन, सार्वजनिक एपीआई का इस्तेमाल करता है, तो उसे इस बात से कोई फ़र्क़ नहीं पड़ना चाहिए कि बैकग्राउंड में 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

    वीटीएस कर्नल कॉन्फ़िगरेशन टेस्ट यह पुष्टि करने में मददगार होता है कि सही कॉन्फ़िगरेशन चालू है या नहीं.

xt_qtaguid को बंद करने की लेगसी प्रोसेस

नया eBPF टूल, xt_qtaguid मॉड्यूल और xt_owner मॉड्यूल की जगह ले रहा है. हम Android कर्नल से xt_qtaguid मॉड्यूल को हटाना शुरू कर देंगे. साथ ही, इसके गैर-ज़रूरी कॉन्फ़िगरेशन बंद कर देंगे.

Android 9 की रिलीज़ में, सभी डिवाइसों पर xt_qtaguid मॉड्यूल चालू होता है. हालांकि, xt_qtaguid मॉड्यूल की proc फ़ाइल को सीधे तौर पर पढ़ने वाले सभी सार्वजनिक एपीआई को NetworkManagement सेवा में ले जाया जाता है. डिवाइस के कर्नल वर्शन और पहले एपीआई लेवल के आधार पर, NetworkManagement सेवा को पता चलता है कि eBPF टूल चालू है या नहीं. साथ ही, यह हर ऐप्लिकेशन के नेटवर्क इस्तेमाल से जुड़े आंकड़े पाने के लिए सही मॉड्यूल चुनती है. एसडीके लेवल 28 या उसके बाद के वर्शन वाले ऐप्लिकेशन को sepolicy, xt_qtaguid proc फ़ाइलों को ऐक्सेस करने से रोकता है.

Android 9 के बाद रिलीज़ होने वाले Android के अगले वर्शन में, ऐप्लिकेशन के लिए उन xt_qtaguid proc फ़ाइलों का ऐक्सेस पूरी तरह से ब्लॉक कर दिया जाएगा. साथ ही, हम नए Android कॉमन कर्नल से xt_qtaguid मॉड्यूल को हटाना शुरू कर देंगे. इसे हटाने के बाद, हम उस कर्नल वर्शन के लिए Android के बेस कॉन्फ़िगरेशन को अपडेट करेंगे, ताकि xt_qtaguid मॉड्यूल को साफ़ तौर पर बंद किया जा सके. Android के किसी वर्शन के लिए कर्नल का सबसे कम वर्शन 4.9 या इससे ज़्यादा होने पर, xt_qtaguid मॉड्यूल पूरी तरह से बंद हो जाएगा.

Android 9 की रिलीज़ में, सिर्फ़ उन डिवाइसों में नई eBPF सुविधा होनी चाहिए जो Android 9 की रिलीज़ के साथ लॉन्च हुए हैं. जिन डिवाइसों में eBPF टूल के साथ काम करने वाला कर्नेल पहले से मौजूद है उनके लिए हमारा सुझाव है कि Android 9 में अपग्रेड करते समय, कर्नेल को नई eBPF सुविधा के साथ अपडेट करें. उस अपडेट को लागू करने के लिए, कोई सीटीएस टेस्ट नहीं है.

Validation

आपको 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 में कुछ टेस्ट हैं, ताकि नए टूल के पूरे व्यवहार की पुष्टि की जा सके.

सीटीएस और सीटीएस वेरिफ़ायर

Android 9 रिलीज़ में, ट्रैफ़िक मॉनिटरिंग के दोनों मॉड्यूल काम करते हैं. इसलिए, सभी डिवाइसों पर नया मॉड्यूल लागू करने के लिए, कोई सीटीएस टेस्ट नहीं है. हालांकि, कर्नेल वर्शन 4.9 से ज़्यादा वाले ऐसे डिवाइसों के लिए, GSI पर CTS टेस्ट उपलब्ध हैं जो मूल रूप से Android 9 के साथ शिप किए गए थे.इसका मतलब है कि पहला एपीआई लेवल >= 28. इन टेस्ट से यह पुष्टि की जाती है कि नया मॉड्यूल सही तरीके से कॉन्फ़िगर किया गया है. TrafficStatsTest, NetworkUsageStatsTest, और CtsNativeNetTestCases जैसे पुराने सीटीएस टेस्ट का इस्तेमाल करके, यह पुष्टि की जा सकती है कि व्यवहार, पुराने यूआईडी मॉड्यूल के मुताबिक है.

मैन्युअल टेस्टिंग

system/netd/ में कुछ यूनिट टेस्ट हैं (netd_unit_test, netd_integration_test और libbpf_test). स्टेटस की मैन्युअल तरीके से जांच करने के लिए, dumpsys का इस्तेमाल किया जा सकता है. dumpsys netd कमांड से, trafficController मॉड्यूल का बुनियादी स्टेटस दिखता है. साथ ही, यह भी पता चलता है कि eBPF सही तरीके से चालू है या नहीं. अगर eBPF चालू है, तो dumpsys netd trafficcontroller कमांड से, हर eBPF मैप का पूरा कॉन्टेंट दिखता है. इसमें टैग किए गए सॉकेट की जानकारी, हर टैग के हिसाब से आंकड़े, यूआईडी और iface, और मालिक के यूआईडी से मैच होने की जानकारी शामिल होती है.

टेस्ट लोकेशन

CTS टेस्ट यहां मौजूद हैं:

वीटीएस टेस्ट यहां मौजूद हैं: https://android.googlesource.com/kernel/tests/+/android16-release/net/test/bpf_test.py.

यूनिट टेस्ट यहां मौजूद हैं: