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, מכשירי אנדרואיד הפועלים על ליבה 4.9 ומעלה ונשלחו במקור עם מהדורת P חייבים להשתמש בניטור תעבורת רשת מבוסס eBPF במקום xt_qtaguid . התשתית החדשה גמישה יותר וניתנת לתחזוקה ואינה דורשת שום קוד קרנל מחוץ לעץ.

הבדלי התכנון העיקריים בין ניטור תעבורה מדור קודם ל-eBPF מומחשים באיור 1.

הבדלים בתכנון ניטור תעבורה מדור קודם ו-eBPF

איור 1. הבדלי תכנון ניטור תעבורה מדור קודם (שמאל) ו-eBPF (ימין).

העיצוב החדש של trafficController מבוסס על מסנן cgroup cgroup וכן על מודול netfilter xt_bpf בתוך הליבה. מסנני eBPF אלה מוחלים על החבילה tx/rx כאשר הם עוברים דרך המסנן. מסנן cgroup eBPF ממוקם בשכבת התחבורה ואחראי לספירת התעבורה מול ה-UID הנכון בהתאם ל-Socket UID כמו גם להגדרת מרחב המשתמש. ה- xt_bpf netfilter מחובר 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 מסוימים בהתאם להגדרות הטלפון. תכונת חסימת התעבורה ברשת מבוססת UID היא תחליף למודול xt_owner בתוך הליבה וניתן להגדיר את מצב הפירוט על ידי כתיבה אל traffic_powersave_uid_map , traffic_standby_uid_map ו- traffic_dozable_uid_map .

ההטמעה החדשה עוקבת אחר ההטמעה של מודול xt_qtaguid מדור קודם לכן, TrafficController ו- NetworkStatsService יפעלו עם ההטמעה הישנה או עם ההטמעה החדשה. אם האפליקציה משתמשת בממשקי API ציבוריים, לא אמור להיות הבדל בין אם נעשה שימוש בכלי xt_qtaguid או eBPF ברקע.

אם ליבת המכשיר מבוססת על ליבת האנדרואיד המשותפת 4.9 (SHA 39c856663dcc81739e52b02b77d6af259eb838f6 ומעלה), אז לא נדרשים שינויים ב-HALs, מנהלי התקנים או קוד ליבה כדי ליישם את כלי ה-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

    מבחן תצורת ליבת VTS מועיל בעת אימות התצורה הנכונה מופעלת.

  2. יש להגדיר את MEM_LOCK MEM_LOCK של המכשיר ל-8 MB או יותר.

תהליך הוצאה משימוש xt_qtaguid מדור קודם

הכלי eBPF החדש מחליף את מודול xt_qtaguid ואת מודול xt_owner שעליו הוא מבוסס. נתחיל להסיר את מודול xt_qtaguid האנדרואיד ולבטל את התצורות המיותרות שלו.

במהדורת אנדרואיד 9, מודול xt_qtaguid מופעל בכל המכשירים, אך כל ממשקי ה-API הציבוריים שקוראים ישירות את קובץ ה-proc של מודול xt_qtaguid מועברים ל- NetworkManagement Service. בהתאם לגרסת ליבת המכשיר ולרמת ה-API הראשונה, שירות NetworkManagement יודע אם כלי eBPF מופעלים ובוחר את המודול המתאים לקבל עבור כל נתון שימוש ברשת אפליקציה. אפליקציות עם SDK ברמה 28 ומעלה חסומות מגישה לקבצי xt_qtaguid proc על ידי sepolicy.

במהדורת אנדרואיד הבאה אחרי 9, הגישה לאפליקציה לקבצי ה-proc של xt_qtaguid תיחסם לחלוטין. נתחיל להסיר את מודול xt_qtaguid הנפוצים של אנדרואיד החדשים. לאחר הסרתו, נעדכן את תצורת הבסיס של אנדרואיד עבור אותה גרסת ליבה כדי לכבות באופן מפורש את מודול xt_qtaguid . מודול xt_qtaguid יבוטל לחלוטין כאשר הדרישה המינימלית לגרסת הליבה עבור מהדורת אנדרואיד היא 4.9 ומעלה.

במהדורת אנדרואיד 9, רק מכשירים שיושקו עם גרסת אנדרואיד 9 נדרשים לקבל את תכונת ה-eBPF החדשה. עבור מכשירים שנשלחו עם ליבה שיכולה לתמוך בכלי eBPF, אנו ממליצים לעדכן אותו לתכונה החדשה של eBPF בעת שדרוג לגרסת אנדרואיד 9. אין בדיקת CTS לאכוף את העדכון הזה.

מַתַן תוֹקֵף

עליך לקחת תיקונים באופן קבוע מגרעיני אנדרואיד נפוצים וממאסטר AOSP של Android. ודא שהיישום שלך עובר את מבחני ה-VTS וה-CTS הרלוונטיים, את netd_unit_test ואת libbpf_test .

בדיקה

ישנם kernel 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, כולל מידע socket מתויג, נתונים סטטיסטיים לכל תג, UID ו-iface, והתאמת UID של בעלים.

מיקומי בדיקה

בדיקות CTS ממוקמות ב:

בדיקות VTS ממוקמות בכתובת https://android.googlesource.com/kernel/tests/+/master/net/test/bpf_test.py .

בדיקות היחידה ממוקמות בכתובת: