ईबीपीएफ़ ट्रैफ़िक की निगरानी करना

eBPF नेटवर्क ट्रैफ़िक टूल, डिवाइस के आखिरी बार बूट होने के बाद से, डिवाइस पर नेटवर्क के इस्तेमाल को मॉनिटर करने के लिए, कर्नेल और उपयोगकर्ता स्पेस के कॉम्बिनेशन का इस्तेमाल करता है. यह सोकेट टैगिंग, फ़ोरग्राउंड/बैकग्राउंड ट्रैफ़िक को अलग करने, और हर यूआईडी फ़ायरवॉल जैसी अतिरिक्त सुविधाएं उपलब्ध कराता है. इससे, फ़ोन की स्थिति के हिसाब से ऐप्लिकेशन को नेटवर्क ऐक्सेस करने से रोका जा सकता है. इस टूल से इकट्ठा किए गए आंकड़ों को, eBPF maps नाम के कर्नेल डेटा स्ट्रक्चर में सेव किया जाता है. NetworkStatsService जैसी सेवाएं, इस नतीजे का इस्तेमाल पिछले बूट के बाद से ट्रैफ़िक के लगातार आंकड़े देने के लिए करती हैं.

उदाहरण और सोर्स

उपयोगकर्ता स्पेस में हुए बदलाव, मुख्य रूप से system/netd और framework/base प्रोजेक्ट में हुए हैं. एओएसपी में डेवलपमेंट किया जा रहा है. इसलिए, एओएसपी कोड हमेशा अप-टू-डेट रहेगा. सोर्स मुख्य रूप से system/netd/server/TrafficController*, system/netd/bpfloader, और system/netd/libbpf/ पर मौजूद होता है. फ़्रेमवर्क में कुछ ज़रूरी बदलाव framework/base/ और system/core में भी किए गए हैं.

लागू करना

Android 9 और उसके बाद के वर्शन वाले ऐसे Android डिवाइसों को xt_qtaguid के बजाय, eBPF-आधारित नेटवर्क ट्रैफ़िक मॉनिटरिंग अकाउंटिंग का इस्तेमाल करना होगा जो कर्नेल 4.9 या उसके बाद के वर्शन पर काम करते हैं और जिन्हें मूल रूप से P रिलीज़ के साथ शिप किया गया है. नया इन्फ़्रास्ट्रक्चर ज़्यादा सुविधाजनक और आसानी से मैनेज किया जा सकता है. साथ ही, इसमें ट्री के बाहर के किसी भी कर्नेल कोड की ज़रूरत नहीं होती.

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

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

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

trafficController का नया डिज़ाइन, हर cgroup eBPF फ़िल्टर के साथ-साथ, kernel में मौजूद xt_bpf नेटफ़िल्टर मॉड्यूल पर आधारित है. ये eBPF फ़िल्टर, फ़िल्टर से गुज़रने पर पैकेट tx/rx पर लागू होते हैं. cgroup eBPF फ़िल्टर, ट्रांसपोर्ट लेयर पर मौजूद होता है. यह सॉकेट यूआईडी और यूज़रस्पेस सेटिंग के आधार पर, सही यूआईडी के हिसाब से ट्रैफ़िक की गिनती करता है. 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 से आने वाले ट्रैफ़िक को ब्लॉक करने के लिए ज़िम्मेदार हैं. यह फ़िल्टर, फ़ोन की सेटिंग के हिसाब से काम करता है. यूआईडी पर आधारित नेटवर्किंग ट्रैफ़िक को ब्लॉक करने की सुविधा, कोर में मौजूद 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 टूल को लागू करने के लिए, एचएएल, ड्राइवर या कर्नेल कोड में कोई बदलाव करने की ज़रूरत नहीं है.

ज़रूरी शर्तें

  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

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

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

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

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

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

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

पुष्टि करें

आपको समय-समय पर Android के सामान्य कर्नेल और Android AOSP के मुख्य वर्शन से पैच लेते रहना चाहिए. पक्का करें कि आपका लागू किया गया तरीका, लागू होने वाले वीटीएस और सीटीएस टेस्ट, netd_unit_test, और libbpf_test को पास कर ले.

टेस्ट करना

kernel net_tests की मदद से यह पक्का किया जा सकता है कि आपने ज़रूरी सुविधाएं चालू की हों और ज़रूरी kernel पैच बैकपोर्ट किए गए हों. इन टेस्ट को Android 9 की रिलीज़ से जुड़े वीटीएस टेस्ट के तौर पर इंटिग्रेट किया गया है. system/netd/ (netd_unit_test और libbpf_test) में कुछ यूनिट टेस्ट मौजूद हैं. netd_integration_test में कुछ टेस्ट मौजूद हैं, ताकि नए टूल के पूरे व्यवहार की पुष्टि की जा सके.

सीटीएस और सीटीएस की पुष्टि करने वाली संस्था

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

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

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

टेस्टिंग की जगहें

सीटीएस टेस्ट की सुविधा यहां दी गई है:

VTS टेस्ट https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py पर मौजूद हैं.

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