مراقبة حركة المرور عبر eBPF

تستخدِم أداة حركة بيانات الشبكة في 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.

التنفيذ

اعتبارًا من الإصدار 9 من نظام التشغيل Android، على أجهزة Android التي تعمل بالإصدار 4.9 من الإصدار kernel أو الإصدارات الأحدث والتي تم شحنها في الأصل مع الإصدار P استخدام ميزة تسجيل مراقبة حركة المرور في الشبكة المستندة إلى eBPF بدلاً من xt_qtaguid. تتميز البنية الأساسية الجديدة بأنها أكثر مرونة وقابلية للصيانة ولا تتطلب أي رمز نواة خارج الشجرة.

يوضِّح الشكل 1 الاختلافات الرئيسية في التصميم بين مراقبة حركة المرور القديمة ومراقبة حركة المرور باستخدام eBPF.

الاختلافات في تصميم ميزة مراقبة عدد الزيارات في الإصدارات القديمة وeBPF

الشكل 1. الاختلافات في تصميم مراقبة حركة المرور باستخدام تقنية eBPF (يمينًا) وتقنية المراقبة القديمة (يسارًا)

يستند تصميم trafficController الجديد إلى فلتر eBPF لكل cgroup بالإضافة إلى xt_bpf وحدة netfilter داخل النواة. يتم تطبيق فلاتر eBPF هذه على إرسال/تلقّي الحزمة عند مرورها عبر الفلتر. يقع فلتر cgroup eBPF في طبقة النقل وهو مسؤول عن احتساب عدد الزيارات بالاستناد إلى رقم التعريف المطلق (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. بالإضافة إلى وظيفة جمع إحصاءات الزيارات، يتحمّل فلتر eBPF‏ trafficController و cgroup أيضًا مسؤولية حظر الزيارات من أرقام تعريف مستخدمين معيّنة استنادًا إلى إعدادات الهاتف. إنّ ميزة حظر حركة بيانات الشبكة المستندة إلى رقم التعريف الفريد (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 أو إصدار أحدث)، لن تكون هناك حاجة إلى إجراء أي تعديلات على HAL أو برامج التشغيل أو رمز النواة لتنفيذ أداة eBPF الجديدة.

المتطلبات

  1. يجب تفعيل الإعدادات التالية في ملف إعدادات kernel:

    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 المستندة إليها. سنبدأ بإزالة وحدة xt_qtaguid من ملف ‎Android kernel وإيقاف إعداداتها غير الضرورية.

في إصدار Android 9، يتم تفعيل xt_qtaguid الوحدة في جميع الأجهزة، ولكن يتم نقل جميع واجهات برمجة التطبيقات العامة التي تقرأ مباشرةًملف proc لوحدة xt_qtaguid إلى خدمة NetworkManagement. استنادًا إلى إصدار نواة الجهاز والمستوى الأول لواجهة برمجة التطبيقات، تحدد خدمة NetworkManagement ما إذا كانت أدوات eBPF مفعّلة وتختار الوحدة المناسبة للحصول على كل إحصاءات استخدام شبكة تطبيق. يتم منع التطبيقات ذات المستوى 28 من حزمة SDK والمستويات الأعلى من الوصول إلى ملفات إجراءات xt_qtaguid بموجب سياسة sepolicy.

في الإصدار التالي من Android بعد الإصدار 9، سيتم حظر وصول التطبيقات إلى ملفات xt_qtaguid proc هذه بالكامل، وسنبدأ في إزالة وحدة xt_qtaguid من نواة Android الشائعة الجديدة. بعد إتمام عملية الإزالة، سنعدّل الإعدادات الأساسية لنظام Android لإصدار kernel هذا بهدف إيقاف وحدة xt_qtaguid بشكل صريح. سيتم نهائيًا إيقاف وحدة xt_qtaguid عندما يصبح الحد الأدنى لمتطلبات إصدار kernel لإصدار Android هو 4.9 أو إصدار أحدث.

في إصدار Android 9، يجب أن تتوفّر ميزة eBPF الجديدة على الأجهزة التي تعمل بالإصدار 9 من نظام التشغيل Android فقط. بالنسبة إلى الأجهزة التي تحتوي على نواة متوافقة مع أدوات eBPF، ننصحك بتحديثها إلى ميزة eBPF الجديدة عند الترقية إلى إصدار Android 9. لا يتوفّر اختبار CTS لفرض هذا التحديث.

التحقُّق

يجب أن تحصل بانتظام على الرقع من نواة Android الشائعة وAndroid AOSP main. تأكَّد من أنّ عملية التنفيذ تجتاز اختبارات VTS وCTS السارية، واختبار netd_unit_test، وlibbpf_test.

الاختبار

هناك kernel net_tests للتأكّد من تفعيل الميزات المطلوبة وطرح التعديلات المطلوبة على kernel. يتم دمج الاختبارات كجزء من اختبارات سلامة النقل في الإصدار 9 من Android. هناك بعض اختبارات الوحدات في system/netd/ (netd_unit_test و libbpf_test). هناك بعض الاختبارات في netd_integration_test للتحقّق من السلوك العام للأداة الجديدة.

أداة التحقق CTS وCTS

بما أنّ كلتا وحدتَي مراقبة الزيارات متوافقتَين مع الإصدار 9 من Android، لا يتوفّر اختبار CTS لإجبار تنفيذ الوحدة الجديدة على جميع الأجهزة. أما بالنسبة إلى الأجهزة التي تعمل بإصدار أقدم من 4.9 من نظام التشغيل الأساسي والتي تم شحنها في الأصل مع إصدار Android 9 (أي المستوى الأول من واجهة برمجة التطبيقات >= 28)، فهناك اختبارات CTS على GSI للتحقّق من ضبط الإعدادات الجديدة للوحدة بشكل صحيح. يمكن استخدام اختبارات CTS القديمة، مثل TrafficStatsTest و NetworkUsageStatsTest وCtsNativeNetTestCases، للتحقّق من السلوك للتأكّد من توافقه مع وحدة UID القديمة.

الاختبار اليدوي

هناك بعض اختبارات الوحدة في system/netd/ (netd_unit_test، netd_integration_test و libbpf_test). تتوفّر أداة dumpsys للتحقّق من الحالة يدويًا. يعرض الأمر dumpsys netd الحالة الأساسية لوحدة trafficController وما إذا تم تفعيل eBPF بشكل صحيح. في حال تفعيل eBPF، يعرض الأمر dumpsys netd trafficcontroller المحتوى التفصيلي لكل ملف برمجي eBPF، بما في ذلك معلومات المقبس المُشارَك، والإحصاءات لكل علامة، ورقم تعريف المستخدم وواجهة المستخدم، ومقتطف UID الخاص بالمالك.

المواقع الجغرافية للاختبار

يمكن العثور على اختبارات CTS على الرابط التالي:

يمكن العثور على اختبارات VTS على الرابط https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py.

تتوفّر اختبارات الوحدات في: