איך לזהות מנהרת VPN פעילה מהקוד בכל פלטפורמה
האם המנהרה קיימת, האם היעד הזה עובר דרכה, או שהקצה המרוחק עונה? אלה שלוש בדיקות שונות ושלושה אותות שונים.
„האם ה-VPN פעיל?” הוא למעשה שלוש שאלות במשפט אחד. איזו מהן הקוד שלך צריך היא ההחלטה הראשונה, והיא זו שרוב המימושים מדלגים עליה. האם קיימת מנהרה במכשיר הזה, האם התעבורה ליעד הזה יוצאת דרכה, או שהקצה המרוחק עונה בזהות שאתה מצפה לה. בחר את התכונה, אחר כך בחר את האות שמודד אותה, ולבסוף אמור ביומן איזו מהן באמת מדדת.
שלוש תכונות, שלושה אותות
כשהן מכווצות לשורה אחת כל אחת, לשלוש השאלות יש שלוש תשובות שונות. הטבלה שלמטה היא ההחלטה עצמה, לא תקציר שלה.
| Property | Signal that answers it | What it still leaves open |
|---|---|---|
| Existence | The platform's own connection state: RAS on Windows, NetworkManager on D-Bus on Linux, scutil on macOS | Tunnels of a type the platform does not manage, which includes most third-party clients |
| Path | A route lookup for the one destination, or a scoped proxy or interface key that names the tunnel | Whether the far end is the peer you trust |
| Identity | An authenticated response from the far end, or a source-address policy applied on the server | Which local interface carried the packets |
קרא את השורה האחרונה לאט. מארח פרטי שעונה מוכיח שמשהו ענה, לא שהתשובה הגיעה דרך המנהרה, והוא לא אומר דבר על מי נמצא בקצה השני. אם התכונה שאתה צריך היא הנתיב, מדוד את הנתיב.
קיום: המצב של הפלטפורמה עצמה
Windows עונה על זה לפרופילים מקוריים דרך Remote Access Service API. הפונקציה RasEnumConnections מפרטת מה מחובר, הפונקציה RasGetConnectStatus מדווחת על מצב של רשומה אחת, והפונקציה RasGetLinkStatistics מוסיפה מהירות, מוני בתים וגיל חיבור. הגבולות הם העיקר: OpenVPN, WireGuard ולקוחות ספקים לעולם אינם רושמים חיבור RAS, ולכן מנהרה בריאה מסוג זה מציגה רשימה ריקה וקוד נאיבי מדווח עליה ככבויה.
שולחנות העבודה של Linux חושפים את אותה תכונה דרך NetworkManager על D-Bus, שם PropertiesChanged על אובייקט חיבור ה-VPN הופך את הבדיקה לאירוע, ותכונת State מדווחת מתי הקישור מגיע למצב מחובר. מתוך מעטפת, nmcli connection show --active קורא את אותו מידע, וזה מה שאתה רוצה בזמן ניפוי שגיאות. macOS שומר את הרשימה הזו במסגרת System Configuration, כאשר scutil הוא התצוגה שלו משורת הפקודה. שלושתם מתארים חיבור שהפלטפורמה מנהלת, ושלושתם שותקים לגבי מנהרה שהיא אינה מנהלת.
נתיב: לאן החבילה באמת הולכת
התאמת שמות היא הקיצור שכולם תופסים ראשון: מנה ממשקים, בדוק את המחרוזת מול tun, tap, ppp או ipsec, והתייחס להתאמה כהוכחה. זהו יוריסטיקה, וקבוצת הממשקים יכולה להיראות זהה בין אם משהו עובר דרכה ובין אם לא. גרסאות iOS ישנות ענו כך והמאוחרות הפסיקו, מפני שהממשקים הנראים כבר לא הבדילו בין שני המצבים.
מה שהחליף זאת שם הוא מילון ה-proxy של המערכת. כל עוד VPN מחובר, קריאת הגדרות ה-proxy מחזירה מפתחות המוגבלים לממשקים הקשורים למנהרה, וכשאין דבר מחובר המילון חוזר ריק. זו הצהרה חלשה מכפי שהיא נשמעת, מפני שהיא מתעדת אמונה של המערכת שקיימת מנהרה, ולא איזה יעד משתמש בה.
ל-Android יש גרסה משלו של המלכודת: שידור vpn.connectivity מגיע למקלטים המוצהרים במניפסט בחלק מהגרסאות ולמקלטים הרשומים בזמן ריצה באחרות. התייחס אליו כמאמץ מיטבי, והשאר בדיקה ישירה מאחוריו.
כשהיעד הוא מה שחשוב, שאל את טבלת הניתוב במקום את רשימת המתאמים. יוריסטיקות של שער ברירת מחדל נשברות במכונות עם כמה רשתות ובמנהרות שמתקינות שער משלהן.
זהות: בדוק את הקצה המרוחק
לולאה ששולחת הד ICMP לקצה המרוחק כל כמה שניות היא הבדיקה הזולה מסוגה, והיא נכשלת בכיוון שימושי. כוון אותה לכתובת שקיימת רק בתוך הרשת הפרטית, מפני שכתובת ציבורית עונה דרך כל קישור עולה שעובד ואינה מוכיחה דבר. במקום שבו ICMP מסונן, חיבור TCP קצר ליציאת השירות עושה את אותה עבודה.
לבדיקה בצד השרת יש בדיוק אות אחד זמין: כתובת המקור של החיבור. תחזוקת מלאי הטווחים היא עבודת תחזוקה, והיא אינה יכולה להפריד מנהרה מכל רשת אחרת שמשתמשת במקרה באותו בלוק.
מדיניות גסה יכולה לחיות עם זה. זהות לא יכולה, לכן אמת את הלקוח במקום לסמוך על המקום שממנו נראים הפקטים שלו מגיעים.
רשום את הקטגוריה, לא את הפסק
הפרד את קטגוריות הכשל ביומן: אין ממשק כלל, ממשק קיים אך היעד אינו נגיש, היעד נגיש אך האימות נדחה. אלה שלושה בעלים שונים, וכל אחד פותח חקירה אחרת.
כיווצם ל„VPN כבוי” אחד שולח את הדוח לצוות שאינו יכול לתקן אותו. הקטגוריה היא הפלט השימושי; הפסק הוא מה שהופך אותו לשגוי.