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

מה הכלל מקבע ומה DNS מחזיר

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

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

שלוש דרכים שבהן ההתאמה נשברת

המקרה הברור הוא שירות שעבר: המפעיל נתן לו כתובת חדשה, DNS עקב, והחריגה לא. השני הוא משפחת כתובות שהכלל מעולם לא כיסה, מה שקורה כששם מתחיל להחזיר רשומות AAAA שחריגה ל-IPv4 בלבד מתעלמת מהן. השלישי הוא הבדל resolver: תצוגה פנימית ותצוגה ציבורית יכולות להחזיר כתובות שונות לאותו שם, כך שהכתובת שהאפליקציה שלכם משתמשת בה אינה זו שאיתה בדקתם.

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

קראו את היעד שהאפליקציה באמת משתמשת בו

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

getent ahosts api.example.com
dig +short api.example.com A
dig +short api.example.com AAAA
ss -tnp | grep -F api
ip route get 203.0.113.40

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

תקנו את המנגנון, לא את התסמין

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

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

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

אמתו את שני חצאי הכוונה

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

curl -sv --max-time 5 https://api.example.com/ -o /dev/null 2>&1 | grep -E 'Trying|Connected to'
curl -sS --max-time 5 https://public.example/ -o /dev/null -w '%{http_code}\n'

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

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