הכלל היה פשוט: לסנן תעבורה רק כשהטלפון מחובר ל-Wi-Fi של המשרד. הוא החזיק חודשים, ואז בוקר אחד הטלפון ישב על אותו SSID עם אותו סמל מפתח והסינון פסק. שום דבר ברשת לא השתנה; מה שהשתנה היה אם האפליקציה יכולה לראות את שם הרשת. ב-Android, «על איזה Wi-Fi אני» ו«חסום את התעבורה הזו» הן שתי משימות נפרדות, וחומת אש שמערבבת ביניהן נפתחת בדיוק כשהשם נעשה לא זמין.

הסימפטום: הזהות נעלמת והמדיניות אחריה

כלל SSID קורא ערך ואז בוחר ענף. כשהקריאה לא מחזירה דבר שימושי, הקוד חייב לעשות משהו, וברירת המחדל הנפוצה היא «זו לא הרשת הצפויה, לכן אל תסנן». ברירת מחדל זו הופכת בעיית הרשאה לדליפת תעבורה. סמל המפתח נשאר גלוי כי שירות ה-VPN עוד רץ; הוא רק אוכף ענף אחר.

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

מדוע השם יכול לחזור כלא מוכר

WifiInfo.getSSID() מחזיר את מזהה קבוצת השירותים של הרשת הנוכחית, ו-Android מתעד שגישה לשדות רגישים למיקום תלויה בהרשאה. כשהגישה אינה זמינה, הקריאה מחזירה UNKNOWN_SSID במקום להיכשל בקול. לכן ערך ריק או לא מוכר אינו הוכחה שהטלפון עזב את ה-Wi-Fi; הוא הוכחה שהאפליקציה אינה יכולה לסווג את הרשת.

שתי בדיקות מפרידות בין המקרים. ודאו שהטלפון משויך וראו מה המערכת מדווחת, ואז ודאו שלאפליקציה באמת יש ההרשאה שהיא צריכה במהדורת Android הזו:

adb shell cmd wifi status
adb shell dumpsys package <your.app> | grep -i -E "ACCESS_FINE_LOCATION|NEARBY_WIFI_DEVICES"

אם שורת המצב מראה רשת מחוברת בעוד האפליקציה רואה שם לא מוכר, יש לכם בעיית הרשאה או בעיה ברמת ה-API, לא בעיית Wi-Fi. תקנו זאת לפני שתיגעו בכללי חומת האש, כי כל כלל בהמשך מוערך מול ערך שהאפליקציה אינה יכולה לקרוא.

היכן הסינון באמת רץ

חומת אש מקומית ב-Android משתמשת בדרך כלל במודל VpnService בלי לשלוח תעבורה לשרת מרוחק: היא לוקחת את הממשק הווירטואלי, מחילה את כלליה שלה ומעבירה הלאה את מה שהיא מתירה. הפלטפורמה מתירה שירות VPN פעיל אחד לכל פרופיל משתמש, והשני מחליף את הראשון במקום להתווסף עליו. לכן אפליקציית חומת אש נפרדת ו-VPN עבודה נפרד אינם יוצרים שרשרת דו-שלבית; אחד מהם מנצח.

זה חשוב לכלל SSID משום שנקודת האכיפה ונקודת התצפית הן רכיבים שונים. ה-VpnService מחליט מה יוצא מהמכשיר; ה-API של Wi-Fi רק מספק תווית. אפליקציה יכולה לאכוף נכון ולסווג לא נכון, וזו בדיוק התקלה במאמר הזה.

תנו למצב הלא מוכר מדיניות משל עצמו

התייחסו לזהות הרשת כאל שלושה מצבים, וכתבו את המדיניות לכל אחד לפני שאתם משחררים את הכלל. המצב השלישי הוא זה שנשכח, והוא זה שתוקף או תצורה שגויה יכניסו אתכם אליו.

ObservationPolicy to specify
Expected SSID is readableThe explicit filtering policy you designed
A different SSID is readableThe default policy for untrusted networks
Unknown, changing or unreadableFail closed until classification is reliable

כשל סגור פירושו שהמצב הלא מוכר יורש את המדיניות הסבירה המחמירה ביותר ולא את הנוחה ביותר. אם זה הופך את הטלפון לבלתי שמיש ברשת חדשה, הפתרון הנכון הוא חריגה מכוונת וגלויה, לא החלטת אמון שקטה החבויה בבדיקת ערך ריק.

SSID מוכר הוא תווית, לא הוכחה למפעיל הרשת. כל אחד יכול להריץ נקודת גישה עם שם המשרד, ולכן התאמת שם לא אמורה להיות הדבר היחיד בין הפעלה רגישה לקטע לא מהימן.

בדקו את המעברים, לא את המצב היציב

בדיקות במצב יציב עוברות ברשת שבה בניתם את הכלל. הכשלים חיים במעברים: הרשאה שנדחתה, מ-Wi-Fi לרשת סלולרית, מ-SSID אחד לאחר, שירות VPN שהופעל מחדש ואפליקציית VPN אחרת שמשתלטת על הממשק. לכל אחד החליטו אם חיבורים קיימים נבחנים מחדש ואם תעבורה מוגנת נשארת חסומה כל עוד המצב לא מוכר.

כתבו את התוצאה בשלושה משפטים: התנאי שנצפה, הרכיב שאוכף את ההחלטה והנסיגה המכוונת. אם אחד מהשלושה חסר, הכלל עדיין אינו מדיניות; הוא ניחוש שעובד במקרה ברשת המשרד.

מאמרים קשורים