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

אפשרות שנדחפה היא הצעה, לא התקנה

בשרת, שתי הנחיות מתארות כוונה ולא השפעה:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

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

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

ודאו שהדחיפה הגיעה ומצאו את הבעלים

התחילו בשם המפעיל: פקודת openvpn חשופה, מופע systemd, NetworkManager או לקוח של ספק. זה קובע היכן hook יכול לחיות. במארח עם systemd-resolved, resolvectl status מפרט כל קישור עם שרתי ה-DNS ותחומי החיפוש שבהם הוא משתמש בפועל, וקישור המנהרה לא תמיד נקרא tun0.

אם הכתובת שנדחפה מופיעה ביומן אך לא על שום קישור, האינטגרציה חסרה. אם היא מופיעה על הקישור והשאילתות עדיין יוצאות למקום אחר, הבעיה היא אילו שאילתות בוחרות את אותו קישור. NetworkManager dns=dnsmasq בקובץ /etc/NetworkManager/NetworkManager.conf מפעיל מעביר מקומי שמיישם DNS מפוצל בכוונה: שמות בתוך תחום ה-VPN הולכים לפותר ה-VPN, וכל השאר שומר על הנתיב הקודם. התנהגות זו נראית כתקלה כשציפיתם שכל התעבורה תעבור; בדקו את ההגדרות לכל חיבור עם nmcli connection show "My VPN", שם ipv4.dns ו ipv4.dns-search מחזיקים בערכים שמאחורי מה שהמכשיר מדווח, לפני שאתם מכנים אותו שבור. אם כל שאילתה באמת אמורה להגיע לפותר ה-VPN, הסירו dns=dnsmasq מ NetworkManager.conf והפעילו מחדש את NetworkManager, מה שמחזיר את פתרון השמות להגדרות החיבור; אחרת השאירו DNS מפוצל ותקנו את רשימת התחומים שנדחפה.

Linux: מסרו את האפשרויות לפותר

חבילות ההפצה מספקות hook לכך, וחייבים לאפשר ללקוח להריץ אותו. סידור טיפוסי במארח ללא systemd-resolved:

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

עם systemd-resolved ייתכן שסקריפט ה-resolv.conf הישן לא ישנה דבר מהותי, כי פותר ה-stub מחזיק מצב לכל קישור. update-systemd-resolved העוזר מתעד צורת hook שמשתמשת ב up-restart ו down-pre, מה שחשוב כשממשק שורד ניסיון חיבור אחד. בכל בחירה שתבחרו, רכיב אחד חייב להחזיק במצב. הוספת hook לא קשור לצד NetworkManager נותנת שני כותבים לאותו קישור, והתוצאה תלויה אז בסדר ולא בתצורה שלכם.

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

Windows ו-macOS מחילים חלקים שונים

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

Get-DnsClientServerAddress -InterfaceAlias "My VPN"
Get-DnsClientNrptPolicy

אם הכתובת חסרה, הגדירו אותה עם Set-DnsClientServerAddress -InterfaceAlias "My VPN" -ServerAddresses 10.8.0.1, ואז הוסיפו את הסיומת למאפייני ה-IPv4 של המתאם כך ש- fileserver יהפוך ל- fileserver.corp.example. ערך SearchList בהיקף המכונה תחת Tcpip\Parameters עושה את אותו הדבר. היכן שהשם הארוך נפתר והחשוף לא, הפותר כבר תקין והאשמה ברשימת החיפוש. התיקונים, לפי הסדר: דחפו DOMAIN כדי שהלקוח ילמד את הסיומת, הוסיפו את הסיומת לרשימת החיפוש של המתאם או החיבור, וכאמצעי זמני הצמידו את השם ב- hosts, או ב- LMHOSTS ב-Windows; גלישת NetBIOS אינה חוצה נתב, ולכן השידור שמוצא שם קצר ב-LAN המשרדי לעולם אינו מגיע ללקוח מנהרה.

block-outside-dns block-outside-dns הוא התנהגות של לקוח Windows, לא שורת פרופיל ניידת, והעתקתו לפרופיל Linux או macOS אינה משחזרת אותה שם. אם שמות ציבוריים עובדים והפנימיים נכשלים ב-Windows, השוו את סדר המתאמים תחת הגדרות מתקדמות עם ipconfig /all. ב-macOS סדר הפותרים לכל שירות שייך למערכת, לכן השתמשו ב- scutil --dns כדי לראות איזה פותר נשאל עבור איזה תחום, והתייחסו לכל תיקון פרופיל בודד שמדווח ככזה שתלוי בלקוח ולא ככללי.

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

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

הוכיחו לאן השאילתה הלכה

לכידה במהלך חיפוש אחד מכריעה את הוויכוח: tcpdump -ni eth0 port 53 מראה שאילתות בממשק הפיזי, כלומר הן יוצאות מחוץ למנהרה והפותר מעולם לא הוחלף. dig @10.8.0.1 name.corp.example ואז מפריד בין שני המקרים הנותרים. אם השאילתה הישירה עונה, הפותר עובד והלקוח אינו משתמש בו; אם היא פגה בזמן, הפותר אינו נגיש דרך המנהרה וכל שינוי מקומי לא יעזור.

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

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

החזיקו בעלים אחד ואמתו לפי הסדר

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

סגרו את הלולאה בארבע בדיקות: הכתובת שנדחפה נוכחת בקישור המנהרה, השם הפנימי נפתר כשם מלא, אותו שם נפתר בלי הסיומת, ושניהם עדיין נכונים לאחר התחברות מחדש אחת. לכידה אחת אומרת לכם איזו מהארבע נכשלה. המדריך של OpenVPN 2.6 מפרט dhcp-option ואת הנחיות הסקריפט עם הערות הפלטפורמה שלהן.

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