שני אנשים שואלים את אותה שאלה ומקבלים תשובות שאינן מתיישבות זו עם זו, מפני שהם עומדים במקומות שונים. לאחד פתוח מסך הגדרות ה-VPN של המערכת והוא עורך רשימה של אפליקציות. השני כותב VpnService.Builder.addDisallowedApplication() בעורך. שניהם קוראים לזה מסנן VPN לפי אפליקציה. רק אחד מהם מחזיק בשליטה שהוא מתאר, ואף אחד מהם אינו חוסם דבר.

התחילו במסך שהמשתמש רואה

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

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

עקבו אחר החבילה אל תוך מנהרה

כאשר האפליקציה שלכם בונה מנהרה, היא יוצרת ממשק TUN ומצהירה איזו תעבורה של אפליקציות נכנסת אליו. קריאות החברות מתרחשות לפני הקמת הממשק, ואחר כך מערכת הכללים קבועה לאותו הפעלה:

val builder = VpnService.Builder()
builder.addAddress("10.8.0.2", 32)
builder.addRoute("0.0.0.0", 0)
builder.addDisallowedApplication("com.example.bypass")
val tun = builder.establish()   // membership decided here

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

למה ההחרגה נראתה כמו חסימה

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

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

מה נשבר כשאתם בונים את זה בעצמכם

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

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

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

בדקו עם אפליקציה שאתם שולטים בה

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

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

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