DNS של ה-VPN תופס כל שאילתה: תקנו את dns-priority ב-NetworkManager
חיבור VPN מקבל כברירת מחדל עדיפות 0 ותובע כל דומיין. הגדירו עדיפות שלילית לסדר, ואז השתמשו בדומייני ניתוב כדי להחזיר את השאר.
התחברו ל-VPN של המשרד ולפתע כל שאילתת שם הולכת ל-resolver הארגוני. שמות ציבוריים עדיין נפתרים, כך שדבר לא נראה שבור עד ששם של מדפסת מקומית נכשל או שרשומת split-horizon מחזירה את כתובת המשרד. בחלק מהתקנות Fedora קורה ההפך: ה-resolver של הספק ממשיך לענות אחרי שהמנהרה עולה. שני המקרים הם שאלה אחת — איזה resolver מחזיק בשאילתה הזו — ובמערכות NetworkManager התשובה חיה במאפייני ה-DNS של כל חיבור.
שני חיבורים, resolver אחד מנצח
כל חיבור מצהיר על עדיפות DNS. חיבורים רגילים מקבלים 50 כברירת מחדל וחיבורי VPN מקבלים 0, והערך הנמוך מנצח. בדיוק ברירת המחדל הזו היא הסיבה שחיבור VPN עוקף בשקט את החיבור הקווי לכל דומיין שהוא תובע: אפס מנצח חמישים בלי שאיש בחר בכך.
העדיפות מסדרת את המועמדים. היא לא מגבילה על מה שואלים את המנצח. חיבור VPN בלי דומיין חיפוש תובע הכול, ולכן העדפתו שולחת גם שאילתות ציבוריות אל תוך המנהרה ובתכנון מנהרה מפוצלת לאן שה-resolver הארגוני מעביר.
העדיפות קובעת את הסדר, רשימת החיפוש קובעת את הבעלות
nmcli -f connection.id,ipv4.dns,ipv4.dns-search,ipv4.dns-priority con show "Corp VPN"
resolvectl status
readlink -f /etc/resolv.conf
רשימת החיפוש היא הצהרת הבעלות. דומיין עירום כמו corp.example הופך לסיומת חיפוש ולדומיין ניתוב. הצורה המיועדת לניתוב בלבד ~corp.example שולחת שאילתות תחת הסיומת הזו לחיבור הזה בלי להוסיף את הדומיין לשמות קצרים. הטילדה הזו היא ההבדל בין «שאל את השרת הזה» ל«שאל את השרת הזה ותסיים את ההקלדה שלי».
השתמשו בשתי הצורות כשמשתמשים מקלידים שמות מארח קצרים והרשומות ממוענות גם בשמות מלאים לחלוטין. השתמשו רק בצורת הניתוב כשאתם רוצים את הפיצול בלי לשנות איך ה-resolver משלים שם עירום.
אחר כך הפכו את ההעדפה למפורשת והפעילו מחדש:
nmcli con modify "Corp VPN" ipv4.dns-priority -100
nmcli con modify "Corp VPN" ipv6.dns-priority -100
nmcli con modify "Corp VPN" ipv4.dns-search "~corp.example,corp.example"
nmcli con up "Corp VPN"
עדיפות שלילית היא הדרך המתועדת לומר «העדף את החיבור הזה», והגדרת שתי משפחות הכתובות שומרת על התנהגות עקבית במארח עם קישוריות IPv6. שינוי המאפיין בלי הפעלה מחדש של החיבור לא משנה דבר ממה שרץ עכשיו, ולכן הרצף מסתיים ב-up מפורש.
תנו ל-systemd-resolved להחזיק בפיצול
תוסף ה-dnsmasq המוגדר כברירת מחדל מזרים שאילתות ל-resolver מקומי אחד, ולכן ההפרדה לפי קישור נשארת גסה. systemd-resolved חושף את הפיצול לפי קישור, והפקודה resolvectl query נוקבת בשם הקישור שענה.
systemctl enable --now systemd-resolved
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
systemctl restart systemd-resolved NetworkManager
resolvectl query build.corp.example
אחרי זה הקישור הארגוני נושא את corp.example ו-resolver ציבורי משרת את השאר. כששאילתה מגיעה לקישור הלא נכון, הפקודה נוקבת בשם הקישור שענה לה, ולדעת את זה עדיף מלדעת רק את הכתובת.
התאימו את תכנון ה-DNS לסוג המנהרה
תכנוני פרטיות ששולחים הכול דרך המנהרה לא צריכים לשאת רשימת פיצול, כי היא תחזיר שמות ציבוריים ל-resolver המקומי ותבטל את הכוונה. תכנוני מנהרה מפוצלת זקוקים לאחת: בלעדיה ה-resolver הארגוני רואה כל שאילתה ציבורית, וההגדרה נשברת ברגע שהמנהרה נופלת.
אחר כך יש את ה-kill switch שחוסם DNS מחוץ למנהרה. שמות נפתרים עבור אזורי המנהרה ונכשלים בכל מקום אחר בזמן שהחיבור בריא לגמרי. התשובות הישימות הן היתר מפורש ל-resolver של ה-LAN או מטמון מקומי שמעביר רק את האזור הארגוני, וכל אחת מהן היא חריגה עם בעלים ולא פגם במנהרה.
פרופיל שמשכתב את תצורת ה-resolver בעליית הממשק מתנהג כמעט אותו דבר: ברגע שה-resolver המקומי אינו נגיש, יפתרו רק השמות שהמנהרה מכירה. בכל מנגנון שיחול, רשמו אילו שמות אמורים לעבוד בכל מצב, ותנו את הרשימה למי שמטפל בדיווחים.
אמתו לפי קישור, ואז שוב אחרי התחברות מחדש
שאלו שם פנימי אחד ושם ציבורי אחד, ואז ראו לאן השאילתה באמת הולכת. עמוד בדיקת דליפות אומר לכם איזה resolver ענה, לא איזה קישור המערכת בחרה, ולכן הוא לא אומר דבר על הסדר שזה עתה הגדרתם.
הריצו את שתי השאילתות שוב אחרי ניתוק והתחברות מחדש. עדיפויות מוחלות מחדש כשחיבור מופעל, וקישור סמלי ישן יכול לשרוד שדרוג שאיש אינו זוכר. מה שתרצו לרשום בסוף הוא איזה resolver מחזיק באיזו סיומת, בתוספת בדיקה שמחזיקה גם מחר.