למה הרשומה שלך ב-/etc/hosts לא מגיעה ל-DNS של ה-VPN
התחברות ל-VPN לא מעלה את /etc/hosts. הפרידו בין חיפוש המערכת לשאילתת DNS ישירה, ואז פרסמו שמות פרטיים דרך אזור מנוהל.
הוספתם שם ל-/etc/hosts, התחברתם ל-VPN וציפיתם שהרשומה תופיע אצל כולם. זה לא קורה, וההפתעה מגיעה בדרך כלל עם תסמין שני: השם נפתר במחשב שלכם ונכשל אצל עמית, מה שנראה כמו שירות DNS שבור של ה-VPN ובעצם קובץ ה-hosts עושה בדיוק את מה שהוא תוכנן לעשות. קובץ hosts הוא תצורת פתרון שמות מקומית, לא עדכון אזור, ושום דבר בחיבור VPN רגיל לא מעלה אותו.
Hosts הוא עקיפה מקומית, לא עדכון אזור
הקובץ הוא רשימה של מיפויים שספריות שירות השמות בודקות לפני שהן שואלות שרת DNS או במקום לשאול אותו. שורה כמו 10.40.0.20 build.corp.example משנה את מה שאפליקציות באותו מחשב אחד מסיקות. היא לא יוצרת רשומה, היא לא עוברת במנהרה, ולשרת ה-DNS שהמנהרה מצביעה עליו אין מושג שהיא קיימת.
לכן הכשל אינו סימטרי. הלקוח שלכם מקבל תשובה מהקובץ. לקוח אחר שואל את שרת ה-DNS של ה-VPN, שמחזיר כלום, והאפליקציה מדווחת שהשם לא קיים. שני המחשבים מתנהגים נכון; רק לאחד מהם יש עקיפה שהשני מעולם לא ראה.
שתי פקודות, שני רכיבים שונים
הדרך המהירה ביותר לעצור את הוויכוח היא להפוך את ההבדל לגלוי בשתי פקודות, שתיהן מורצות בלקוח שיש בו את רשומת ה-hosts:
getent ahosts build.corp.example
dig @10.40.0.53 build.corp.example A
הראשונה שואלת את נתיב החיפוש של המערכת עצמה, שבמערכת glibc טיפוסית קורא קבצים מקומיים לפני DNS. השנייה שולחת שאילתת DNS ישירות לשרת בכתובת הזו ואינה בודקת קבצים מקומיים כלל. כשהראשונה מחזירה את הרשומה שלכם והשנייה מחזירה NXDOMAIN, הוכחתם שהרשומה לא קיימת ב-DNS ושהמחשב שלכם עונה מעקיפה מקומית.
הסדר ניתן להגדרה, וכדאי לבדוק אותו לפני שמסיקים משהו על הפצה מסוימת. הביטו בשורה hosts: בקובץ /etc/nsswitch.conf; hosts: files dns בודק קבצים ראשון. אל תעתיקו את הדוגמה הזו על תצורה עובדת רק כדי לשנות את הסדר, כי מערכות אמיתיות מרבות לפרט מקורות נוספים ורשומות שירות מותנות שהדוגמה אינה כוללת.
systemd-resolved מטשטש את הבדיקה
במערכת שמשתמשת ב-systemd-resolved, ה-stub המקומי גם מגיש שמות ממסד הנתונים של hosts. לכן שאילתה אל 127.0.0.53 אינה בדיקה עצמאית של השרת המרוחק, אף שהיא נראית כמו שאילתת DNS ומתנהגת כמוה. אתם יכולים לאשר מה ה-resolver יודע ואילו שרתים הוא היה שואל באמצעות:
resolvectl query build.corp.example
resolvectl status
פלט status מציין את שרתי ה-DNS לכל קישור, וכך אתם מגלים אם קישור ה-VPN בכלל קיבל resolver. השאלה הזו נפרדת מרשומת ה-hosts והיא זו ששווה לשאול כששם פרטי נכשל אצל כל המשתמשים ולא אצל אחד.
אפליקציות יכולות להוסיף שכבה נוספת. דפדפן עם הגדרת DNS-over-HTTPS משלו, מכולה עם תצורת resolver משל עצמה, או סביבת הרצה ששומרת חיפושים במטמון לכל חיי התהליך יכולים כל אחד לענות אחרת מהמערכת. בדקו את האפליקציה שאכפת לכם ממנה במקום להניח שפקודה אחת מתארת כל תוכנית במחשב.
מה באמת חולק שם דרך ה-VPN
אם שם פרטי צריך לעבוד אצל כולם, הוא צריך בעלים שה-resolver של כולם יכול להגיע אליו. התשובה הנקייה היא לפרסם את הרשומה באזור מנוהל ולהפוך את האזור הזה לפתיר דרך נתיב ה-DNS המיועד של ה-VPN. אז לרשומה יש מקור אמת אחד, עקבות ביקורת ומחזור חיים, ואיש לא צריך לזכור איזה מחשב נייד נושא עקיפה מקומית.
הפצת קובצי hosts היא חלופה לגיטימית, והיא ניהול נקודות קצה ולא שירות שמות. אם תבחרו בה, הקובץ חייב להיות מוטמע, מגורסן ומוסר על ידי מה שמנהל את הצי, וכך צריך לתאר אותה בתכנון. „ה-VPN מטפל בזה“ אינו תיאור של התהליך הזה.
רישום DNS דינמי הוא מנגנון שלישי, עם הרשאות משלו, אימות עדכונים ותוחלת חיים של רשומה. הוא אינו נובע מרשומת hosts, והוא גם אינו נובע מלקוח שרק מתחבר, אלא אם השרת והלקוח הוגדרו שניהם לעשות זאת. רשומה שמופיעה מעצמה היא סימן שמישהו הפעיל עדכונים מאובטחים ולקוח שמרשום את עצמו, והתצורה הזו שייכת לרשומת התכנון ולא לשרשור פתרון תקלות. אם איש אינו יכול לנקוב במי הבעלים של ההגדרה הזו, התייחסו לרשומה האוטומטית כלא מאומתת והשאירו את האזור המנוהל כמקור האמת.
שם שנפתר אינו מסלול
פתרון שמות ונגישות הם דברים נפרדים, ומיפוי מקומי מיושן הוא הדרך הקלאסית לבלבל ביניהם. רשומת hosts שמצביעה על כתובת שעברה תמשיך לבחור במארח המיושן זמן רב אחרי ש-DNS תוקן, והתסמין נראה כמו כשל ניתוב בשם שנפתר היטב.
לכן כשהדיווח הוא „השם נפתר אבל השירות אינו נגיש“, השוו את חיפוש המערכת לשאילתה מפורשת אל שרת ה-DNS של ה-VPN, ואז בדקו את הכתובת שקיבלתם מול זו שהשירות משתמש בה בפועל. התיעוד של systemd-resolved מתעד את המקורות המקומיים שהוא בודק, וזו המפה שדרושה לכם להשוואה הזו.
אחר כך תקנו את העקיפה דרך הבעלים שלה. הסרת שורה מקובץ ה-hosts שלכם לא עושה דבר לשנים־עשר המחשבים הניידים שקיבלו את אותה שורה מסקריפט פריסה, וזו הגרסה של הבעיה הזו שיש לאנשים באמת.