مراقبة حركة المرور عبر 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 proc من خلال سياسة الأمان.

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

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

التحقُّق

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

الاختبار

هناك اختبارات net_tests للنواة لضمان تفعيل الميزات المطلوبة وإعادة استخدام الإصلاحات المطلوبة للنواة. يتم دمج الاختبارات كجزء من اختبارات سلامة النقل في إصدار Android 9. هناك بعض اختبارات الوحدات في 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، بما في ذلك معلومات المقبس المُشارَك، والإحصاءات لكل علامة، ورقم تعريف المستخدم وواجهة المستخدم، ومقتطف مطابقة رقم تعريف مستخدم المالك.

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

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

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

يمكن العثور على اختبارات الوحدة في: