למה אפליקציית Android חסומה עדיין מציגה שימוש ברשת
מונה שימוש מודד בייטים בגבול אחד, לא בקשה מוצלחת. בדקו את חלון הזמן, את הייחוס ל-UID ואת השאלה איזו אפליקציה מחזיקה בשירות ה-VPN.
אתם חוסמים אפליקציה בחומת האש של ה-VPN באנדרואיד, האפליקציה מפסיקה לעבוד, ושורת השימוש שלה ממשיכה לטפס. המסקנה המפתה היא שהחסימה דלפה, או שהמונה מקולקל. אף אחת מהן לא נובעת. רשומת שימוש אומרת שבייטים יוחסו לאותה זהות בנקודת תצפית כלשהי; היא לא אומרת דבר על השאלה אם שירות מרוחק קיבל בקשה. ברגע שאתם יודעים איזה גבול נמדד ולאיזו זהות זה חויב, שתי התצפיות מפסיקות לסתור זו את זו.
המונה מודד בייטים, לא מסירה
אנדרואיד מייחס תעבורה ל-UID וסופר אותה בשני הכיוונים, והוא עושה זאת בגבול ממשק ולא ברגע שבו בקשת האפליקציה מצליחה.
ניסיון חיבור שנדחה עדיין מזיז מנות: ה-SYN, האיפוס או השידורים החוזרים שאחריהם, בתוספת שאילתת ה-DNS שקדמה לשניהם. הבייטים האלה קיימים גם כששום דבר לא נמסר, ובחלק מהמסלולים הם נספרים לפני שכל מסנן מחליט מה לעשות איתם.
לכן השורה של אפליקציה חסומה יכולה לגדול בעוד כל בקשה נכשלת. המונה עונה על השאלה "כמה בייטים יוחסו לזהות הזו", לא "האם הזהות הזו הגיעה לאינטרנט". תרשים לא יכול להבחין בין זרם שהתקבל לבין לחיצת יד שנדחתה בנימוס, וגם לא סכום שמחבר את שני הכיוונים יחד.
הייחוס הולך אחרי ה-UID, לא אחרי הסמל
השורה היא לפי UID, ו-UID אחד יכול להיות משותף ליותר מחבילה אחת, בעוד אפליקציה גלויה יכולה להעביר עבודה לרכיב נפרד שרץ תחת זהות משלו. לשונית דפדפן שמצוירת על ידי תהליך WebView משותף, שירות סנכרון ברקע או חבילה נלווית המותקנת לצד האפליקציה הראשית, כולם מייצרים תעבורה שמסך השימוש עשוי להציג תחת שם שלא ציפיתם לו, או תחת האפליקציה שחסמתם. חבילה חסומה ועוזר שנושא את בקשותיה הם שני נשואים שונים, והכלל כיסה רק אחד מהם.
כשהמספרים נראים שגויים, השוו את ה-UID ולא את התווית. ה-API של השימוש נשאל לפי UID, ו-adb shell dumpsys package <package> | grep userId= מדפיס את המספר שכנגדו להשוות, כך ששתי רשומות עם אותו UID הן אותה זהות מנקודת המבט של המונה.
ייתכן שחלון הזמן קודם לכלל שלכם
נתוני שימוש נאספים בדליים ונשאלים מדי פעם, לא מוזרמים בזמן אמת. סכום יומי יכול לכלול את הדקות שלפני הפעלת החסימה, סנכרון רקע מהשעה הקודמת, או תעבורה שכבר הייתה בדרך. השוואת סכום מצטבר לבקשת אחת שנדחתה וקריאה להפרש דליפה היא שגיאת מדידה, לא ממצא של חומת אש.
השתמשו בחלון קצר יותר ובהתחלה נקייה. רשמו את חותמת הזמן כשאתם משנים את הכלל, המתינו למרווח איסוף אחד, ואז הסתכלו רק על נתונים שאחריו. אם הסכום ממשיך לעלות בחלון שמתחיל אחרי הכלל, יש לכם מה לחקור; אם הוא מפסיק לעלות, הצמיחה המוקדמת הייתה היסטוריה שמוצגת.
ייתכן ששירות ה-VPN אינו זה שהגדרתם
חומת אש של VPN רואה רק תעבורה שהשירות שלה עצמו נושא. אם אפליקציית VPN אחרת עולה ומשתלטת על החיבור הפעיל, המסנן שלכם כבר לא במסלול בזמן שהממשק שלו עדיין קיים בהגדרות. רשימות עקיפה לפי אפליקציה עושות זאת בכוונה, ופרופיל שמחריג אפליקציה אינו דליפה כשהאפליקציה עובדת לאחר מכן.
IPv4, IPv6 ו-DNS יכולים גם להתפצל. מסנן שמטפל ב-IPv4 עשוי להשאיר את IPv6 או פותר DNS פרטי מחוצה לו, כך שחלק מתעבורת האפליקציה עוקב אחרי מסלול שהכללים שלכם מעולם לא תיארו. בדקו איזו אפליקציה מחזיקה כעת ב-VPN ומה אומרת רשימת ההחרגות לפני שתכתבו מחדש משהו:
adb shell settings get secure always_on_vpn_app
adb shell dumpsys connectivity
adb shell dumpsys netstats detail
בדקו בקשה חדשה אחת ותעדו ארבע עובדות
בחרו בקשה בלתי מזיקה, עשו אותה פעם אחת, ורשמו ארבע עובדות: הכלל בתוקף, ה-UID של האפליקציה, מצב הרשת והשעה. לאחר מכן בדקו אם המסנן שלכם תיעד את הזרימה, ואם היעד או השער ראו את אותו חיבור. זרימה אחת שזוהתה בשני הצדדים היא ראיה; סכום מצטבר אינו ראיה.
מסקנה ניתנת להגנה נוקבת במה שנדחה ובאיזו תצפית אישרה אותו. "המונה עלה" אינה ממצא, ו"כל מוני השימוש מזויפים" גם לא. סיסמה של שכבת OSI לא מכריעה את זה: התשובה הכנה היא שהמונה והחסימה יכולים להיות שניהם נכונים בעודם מתארים דברים שונים. תיעוד NetworkStatsManager של אנדרואיד מתאר כיצד הדליים האלה נשאלים ומיוחסים.