איך כללי דומיין של Apple VPN On Demand מפעילים מנהרה
כלל דומיין קובע רק מתי המנהרה נפתחת. איך עובדת בדיקת ה-DNS של connect-if-needed, למה נתיבים עדיין בוחרים תעבורה ואיך לבדוק את הפרופיל.
המנהרה נפתחת כשאתם מבקשים שם פנימי אחד ונשארת סגורה כשהאפליקציה הבאה זקוקה לו באותה מידה. זה לא באג באפליקציה; זו הצורה של כלל דומיין. תצורת ה-on-demand של Apple מתארת תנאים ליצירת חיבור, וצורת הדומיין של התנאים האלה שואלת את פותר המערכת שאלה לפני שזז אפילו מנה אחת. שתי שאלות מתבלבלות כל הזמן: מתי המנהרה צריכה לעלות, ומה המנהרה נושאת לאחר שהיא קיימת. הראשונה היא טריגר, השנייה היא מדיניות נתיבים ופותר, ופרופיל אחד בדרך כלל מגדיר את שתיהן באותו payload, ולכן כלל דומיין נכון עדיין יכול להשאיר אתכם ברשת הלא נכונה.
הטריגר ובחירת התעבורה נמצאים בשכבות שונות
כלל on-demand חי במילון ה-on-demand של payload VPN: רשימה מסודרת של כללים, לכל אחד פעולה וקבוצה של תנאי התאמה. המערכת מעריכה אותם כשהקישוריות משתנה או כשמשהו מנסה להגיע לרשת, והפעולה מחליטה אם המנהרה מועלית, מוערכת, מנותקת או מתעלמת. כל זה קורה בשכבת הרשת של הפלטפורמה, לפני שלאפליקציה שלכם יש socket.
מה שקורה אחר כך הוא קבוצה נפרדת של מפתחות: הגדרות IPv4 ו-IPv6 של המנהרה, הנתיבים הכלולים והמוחרגים שלה, כתובות שרתי ה-DNS שלה, וב-iOS וב-iPadOS המיפוי לפי אפליקציה שקובע אילו אפליקציות רשאיות להשתמש במנהרה בכלל. פרופיל יכול לזווג טריגר רחב עם נתיב צר, או טריגר צר עם נתיב ברירת מחדל. קראו רק חצי אחד והחצי השני ייראה כמו תקלה.
יש לי פרופיל מעבדה שמתחבר בכל פעם שמבקשים משהו תחת דומיין פנימי אבל מנתב רק /16 אחד למנהרה. הוא עושה בדיוק מה שה-payload שלו אומר, והוא גם מסוג הפרופילים שמייצרים קריאות שירות: אנשים מניחים שמנהרה מחוברת אומרת שהתעבורה שלהם בתוכה.
מה כלל דומיין באמת שואל את הפותר
צורת הדומיין של הכלל, שנקראת לעתים קרובות connect-if-needed, לא בוחנת payload של מנות ולא צופה בכתובות URL. כששם נפתר, המערכת משווה אותו לדומיינים בכלל, ובהתאמה שואלת אם אפשר לפתור את השם דרך שרתי ה-DNS שהמנהרה מספקת. אם הפותר של המנהרה עונה, השם נחשב פנימי והחיבור מתחיל. אם הפותר המקומי עונה במקום, השם נחשב חיצוני ולא מופיעה מנהרה. סקירת הפריסה של Apple מתארת זאת כזיהוי רשת ואחריו הערכת חיבור.
שתי השלכות נובעות מכך. הפרופיל חייב לציין שרתי DNS בתוך המנהרה; לכלל דומיין בלי פותר מנהרה אין מה להשוות, ולכן ההערכה לא יכולה להפיק את ההתאמה שאתם מצפים לה. והחיפוש חייב להגיע לפותר המערכת. אפליקציה או דפדפן שמריצים DNS מוצפן משלהם, הרחבה שעונה מקומית, או חיבור לכתובת מילולית לא מייצרים לעולם את פתרון השם שהכלל חיכה לו. אחד מהצהריים הארוכים ביותר שביליתי הסתיים כשגיליתי שהלקוח שלפני המנהרה השתמש ב-DNS over HTTPS.
גם מטמון מסיר את הטריגר. שם שכבר נמצא במטמון עשוי להיענות בלי הבדיקה שהייתה מפעילה את המנהרה, ולכן כלל שעבד אתמול נכשל אחרי אתחול, או אחרי שהמנהרה עמדה למעלה זמן מה. ב-macOS sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder מאפס את המצב; ב-iOS הפעלה וכיבוי של מצב טיסה או אתחול המכשיר נותנים לכם התחלה נקייה דומה.
היקף ההתאמה: שמות, אפליקציות ורשתות
התאמת דומיין היא סוג אחד מבין כמה. כלל יכול להתאים גם לסוג הממשק (Wi-Fi, סלולרי, Ethernet) ול-SSID מסוים, ורשומות לפי אפליקציה או דומיין Safari קושרות מנהרה לתהליך עבודה אחד. הקישור הזה מסביר את החוויה המוזרה שבה רק אפליקציה אחת מתנהגת אחרת מכל השאר: שאר האפליקציות מחוץ להיקף המנהרה, ולכן הן ממשיכות להשתמש בנתיב המקומי גם כשסמל המנהרה אומר מחובר.
הסדר חשוב יותר ממה שאנשים מצפים. כללים מוערכים לפי סדר והראשון שמתאים מספק את הפעולה, ולכן כלל רחב של התחברות-בכל-Wi-Fi שממוקם מעל כלל דומיין צר ינצח בשקט ויהפוך את כלל הדומיין לבלתי ניתן לבדיקה. לפני שתכתבו מחדש את רשימת הדומיינים, ודאו שאף כלל קודם לא התאים כבר.
זו גם הסיבה ש-always-on אינו רק כלל on-demand מחמיר יותר. אכיפת always-on היא מצב פריסה נפרד עם דרישות פיקוח וניהול משלו; היא מחזיקה מנהרה פתוחה במקום להגיב לשם. אם מה שאתם צריכים הוא מנהרה שלעולם לא נופלת, כלל דומיין הוא הכלי הלא נכון.
מצבי כשל שמחקים כלל שבור
רוב הדיווחים שכלל דומיין לא עובד נופלים לאחד מחמישה מקומות, ורק האחרון שבהם הוא טקסט הכלל.
| What you see | Layer | First check |
|---|---|---|
| Tunnel comes up, internal site still fails | route or resolver after connect | netstat -rn, scutil --dns |
| Tunnel never comes up for that name | trigger path | fresh lookup, cache flush, private DNS |
| Tunnel comes up for every app | scope, or an earlier rule | rule order, per-app mapping |
| Tunnel drops and will not return on the same Wi-Fi | interface or SSID match, admission | captive portal, SSID string, auth prompt |
| Tunnel returns after you disconnect it | profile ownership | profiles show |
פורטלי captive ראויים לשורה משלהם, כי ה-Wi-Fi של מלונות ושדות תעופה מיירט בדיוק את החיפוש שהכלל תלוי בו. עד שהפורטל יכניס את המכשיר, שרת ה-DNS של המנהרה אינו נגיש, הבדיקה נכשלת, והכשל נראה כמו דומיין עם שגיאת כתיב. אימות הוא המקרה השקט האחר: הכלל יכול לירות, המנהרה יכולה להתחיל להתחבר, והחיבור מת על תעודה שפגה או על בקשה שמופיעה בצג אחר.
IPv6 יוצר וריאציה שקל לאבחן לא נכון. שם עם שתי משפחות כתובות עשוי להיענות קודם מרשומת AAAA, בעוד רשימת הנתיבים של המנהרה נושאת רק IPv4. דפדפן אחד מצליח, אחר נכשל, ורשימת הדומיינים חפה מכל אשמה.
בדקו עם בקשה אמיתית, בסדר הזה
קראו את המדיניות לפני שאתם מנחשים. ב-macOS sudo profiles show -type configuration מדפיס פרופילים מותקנים כולל payload ה-VPN, scutil --nc list מציג את מצב השירות, ו-scutil --nc show <service> מדפיס את מילון ה-on-demand שהמערכת משתמשת בו. ב-iPhone או iPad מנוהלים אותו payload מגיע ממסוף הניהול או מדוח MDM. יומני רשת זמינים עם log stream --predicate 'subsystem == "com.apple.networkextension"' ב-macOS, ודרך מסוף המכשיר כשהטלפון מחובר.
אחר כך בדקו עם שם מארח שלא נשאל קודם בסשן. בחרו שם באזור ה-DNS של המנהרה שאתם יודעים שנפתר פנימית, בקשו אותו פעם אחת, וצפו אם המנהרה מופיעה. הריצו את אותו חיפוש פעמיים: הניסיון השני מפעיל את נתיב המטמון, וההבדל בין השניים אומר לכם אם הטריגר הוא הפתרון או הניתוב.
לאחר שהמנהרה למעלה, אמתו את שתי השכבות בנפרד. netstat -rn -f inet ו-netstat -rn -f inet6 מראים לאן כל קידומת מצביעה, scutil --dns מראה את סדר הפותרים ואיזה ממשק מחזיק בכל פותר, ו-nettop -m route מראה איזה ממשק נשא את הבתים. אם המנהרה למעלה והפותר נכון אבל המשאב עדיין נכשל, הפסיקו לערוך את הכלל; בדקו הרשאה בצד השרת ואת נתיב החזרה.
כשהכלל שייך למישהו אחר
אם המנהרה מופיעה שוב אחרי שניתקתם אותה, הכלל בדרך כלל שייך לפרופיל ולא לאפליקציה: תצורה שנדחפה ב-MDM, פרופיל אישי שנשאר, או פרופיל שהותקן על ידי לקוח אחר. sudo profiles show -type configuration בתוספת חיפוש אחר מפתחות ה-on-demand יצמצם אותו, ונתיב ההסרה הוא הפרופיל, לא המתג בשורת התפריטים. מחיקת רשומת השירות או האפליקציה משאירה את הכלל מאחור, וההתקנה הבאה יורשת אותו שוב.
בדיקה אחת מכריעה בעלות: נתקו, המתינו, בקשו שוב את השם הפנימי. אם המנהרה חוזרת, הטריגר עובד כמתוכנן והשאלה הפתוחה היא מי מנהל אותו והאם ההיקף הזה הוא מה שאתם רוצים.
לפני שתדווחו על זה כבאג, עברו על אותן חמש בדיקות: כתובות הפותר של המנהרה קיימות ב-payload, שם שלא היה במטמון, אף כלל קודם שכבר התאים, נתיב AAAA שרשימת הנתיבים מכסה, והאפליקציה בתוך היקף המנהרה. כשכל החמישה מתקיימים, הכלל עושה את עבודתו והתקלה נמצאת בהמשך הנתיב.