نظارت بر ترافیک 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 نیز هستند.

پیاده سازی

با شروع Android 9، دستگاه‌های Android که روی هسته 4.9 یا بالاتر اجرا می‌شوند و در اصل با نسخه P عرضه می‌شوند، باید به جای xt_qtaguid از حسابداری نظارت بر ترافیک شبکه مبتنی بر eBPF استفاده کنند. زیرساخت جدید انعطاف پذیرتر و قابل نگهداری تر است و نیازی به کد هسته خارج از درخت ندارد.

تفاوت های اصلی طراحی بین نظارت بر ترافیک قدیمی و eBPF در شکل 1 نشان داده شده است.

تفاوت‌های طراحی نظارت بر ترافیک میراث و eBPF

شکل 1. تفاوت طراحی نظارت بر ترافیک میراث (چپ) و eBPF (راست).

طراحی جدید trafficController بر اساس فیلتر eBPF برای هر cgroup و همچنین ماژول فیلتر شبکه xt_bpf در داخل هسته است. این فیلترهای eBPF هنگام عبور از فیلتر روی بسته tx/rx اعمال می شوند. فیلتر cgroup eBPF در لایه انتقال قرار دارد و مسئول شمارش ترافیک در برابر UID سمت راست بسته به 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 بخواند. علاوه بر عملکرد جمع‌آوری آمار ترافیک، trafficController و فیلتر eBPF cgroup نیز بسته به تنظیمات تلفن، مسئول مسدود کردن ترافیک از UIDهای خاص هستند. ویژگی مسدود کردن ترافیک شبکه مبتنی بر UID جایگزینی برای ماژول xt_owner در داخل هسته است و حالت جزئیات را می توان با نوشتن در traffic_powersave_uid_map ، traffic_standby_uid_map و traffic_dozable_uid_map پیکربندی کرد.

پیاده‌سازی جدید از پیاده‌سازی ماژول قدیمی xt_qtaguid پیروی می‌کند، بنابراین TrafficController و NetworkStatsService با پیاده‌سازی قدیمی یا جدید اجرا می‌شوند. اگر برنامه از 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 مبتنی بر آن می شود. ما شروع به حذف ماژول xt_qtaguid از هسته اندروید و غیرفعال کردن تنظیمات غیر ضروری آن می کنیم.

در نسخه اندروید 9، ماژول xt_qtaguid در همه دستگاه‌ها روشن است، اما همه APIهای عمومی که مستقیماً فایل proc ماژول xt_qtaguid را می‌خوانند به سرویس NetworkManagement منتقل می‌شوند. بسته به نسخه هسته دستگاه و سطح اول API، سرویس NetworkManagement می‌داند که آیا ابزارهای eBPF روشن هستند یا خیر و ماژول مناسبی را برای دریافت آمار استفاده از شبکه هر برنامه انتخاب می‌کند. برنامه‌های دارای SDK سطح 28 و بالاتر از دسترسی به فایل‌های xt_qtaguid proc توسط سیاست‌گذاری مسدود شده‌اند.

در نسخه بعدی اندروید پس از 9، دسترسی برنامه به آن فایل‌های xt_qtaguid proc به طور کامل مسدود می‌شود، ما شروع به حذف ماژول xt_qtaguid از هسته‌های رایج جدید اندروید خواهیم کرد. پس از حذف، پیکربندی پایه اندروید را برای آن نسخه هسته به‌روزرسانی می‌کنیم تا ماژول xt_qtaguid به صراحت خاموش شود. ماژول xt_qtaguid زمانی که حداقل نسخه هسته مورد نیاز برای نسخه اندروید 4.9 یا بالاتر باشد به طور کامل منسوخ می شود.

در نسخه اندروید 9، تنها دستگاه هایی که با نسخه اندروید 9 راه اندازی می شوند، باید ویژگی جدید eBPF را داشته باشند. برای دستگاه‌هایی که دارای هسته‌ای هستند که می‌توانند از ابزارهای eBPF پشتیبانی کنند، توصیه می‌کنیم هنگام ارتقا به نسخه اندروید 9، آن را به ویژگی جدید eBPF به‌روزرسانی کنید. هیچ تست CTS برای اجرای آن به روز رسانی وجود ندارد.

اعتبار سنجی

شما باید به طور مرتب وصله هایی را از هسته های رایج اندروید و AOSP اصلی اندروید دریافت کنید. مطمئن شوید که پیاده سازی شما تست های VTS و CTS قابل اجرا، netd_unit_test و libbpf_test را گذرانده است.

تست کردن

هسته net_tests وجود دارد تا اطمینان حاصل شود که ویژگی‌های مورد نیاز را روشن کرده‌اید و وصله‌های هسته مورد نیاز را بکپورت کرده‌اید. این تست ها به عنوان بخشی از تست های VTS انتشار اندروید 9 یکپارچه شده اند. تعدادی تست واحد در system/netd/ وجود دارد ( netd_unit_test و libbpf_test ). تست‌هایی در netd_integration_test برای تایید رفتار کلی ابزار جدید وجود دارد.

تایید کننده CTS و CTS

از آنجایی که هر دو ماژول نظارت بر ترافیک در نسخه اندروید 9 پشتیبانی می‌شوند، هیچ تست CTS برای اجرای ماژول جدید در همه دستگاه‌ها وجود ندارد. اما برای دستگاه‌هایی با نسخه هسته بالاتر از 4.9 که در ابتدا با نسخه اندروید 9 عرضه می‌شوند (یعنی اولین سطح API >= 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 و iface و مطابقت UID مالک را نشان می‌دهد.

مکان های تست

تست های CTS در آدرس زیر قرار دارند:

تست‌های VTS در https://android.googlesource.com/kernel/tests/+/main/net/test/bpf_test.py قرار دارند.

آزمون های واحد در: