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

התחילו במסלול שהמנה תיקח

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

ip route get 203.0.113.10
ip route get 10.20.5.7

ב-Windows, Find-NetRoute -RemoteIPAddress 203.0.113.10 שימושי יותר מ-route print -4 מאותה סיבה: הוא מדווח על המסלול שניצח, לא על כל המסלולים שקיימים. בכל זאת קראו את הטבלה פעם אחת בגלל השורה 0.0.0.0 שלה. זוג /1 שם אומר שלקוח מנהרה מלאה שכתב את ברירת המחדל: האפשרות redirect-gateway def1 של OpenVPN מתקינה 0.0.0.0/1 ו-128.0.0.0/1 דרך המנהרה, וזה מנצח את 0.0.0.0/0 הקיים בהתאמת התחילית הארוכה ביותר בלי למחוק את ברירת המחדל הפיזית. לכן שתי ברירות מחדל יכולות להתקיים יחד בזמן שהכול עדיין נכנס למנהרה.

שני פרטים הופכים את הטבלה לשקרנית. ראשית, הסתכלו על התחילית שהתאימה ולא על מספר ברירות המחדל, משום שמדד הממשק או זוג /1 קובעים את המנצח. שנית, חיבור שכבר קיים שומר על הנתיב שאיתו נוצר; אחרי שהמנהרה עולה, הפעלה פתוחה עשויה להמשיך להשתמש במסלול הישן עד שהיא מאותחלת מחדש, ולכן התחברות מחדש נראית כמו תיקון של בעיית ניתוב. לקוח פועל — ps ax | grep openvpn — מוכיח רק שהתהליך התחיל.

עקבו אחר שם פנימי אחד ושם ציבורי אחד

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

traceroute intranet.corp.example
traceroute 1.1.1.1

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

ICMP מסונן הופך את הבדיקה הזו לשקרנית: כוכביות בשני הנתיבים נראות כמו מנהרה מתה ובדרך כלל זה חומת אש. בדקו פורט TCP היכן שאפשר — traceroute -T -p 443 בלינוקס — וזכרו שהנתיב לא אומר איזה פותר ענה: שם יכול להיפתר מקומית ועדיין להיות נגיש דרך המנהרה.

לכדו במתאם הפיזי, לא במנהרה

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

sudo tcpdump -ni eth0 udp port 53
sudo tcpdump -ni eth0 host 10.20.0.5

המסנן הראשון תופס פתרון שמות שיוצא מקומית, וזו הדליפה הנפוצה והשקטה ביותר — הדף עדיין נטען, רק הפותר ראה את השאילתה. השני תופס תעבורה רגילה לכתובת פנימית שאמורה להתקיים רק בתוך המנהרה. ב-Windows, pktmon עושה את אותה עבודה בלי דרייבר: pktmon filter add -p 53, אחר כך pktmon start --capture --pkt-size 128, אחר כך pktmon stop ו-pktmon format pktmon.etl -o capture.txt. הדגלים האלה משתנים מעט בין גרסאות Windows, לכן בדקו את pktmon filter add /? לפני שאתם בוטחים בתחביר.

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

שאלו שירות חיצוני, ואחר כך שאלו אותו שוב לכל יישום

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

sudo curl --interface tun0 https://example.net/ip
sudo curl --interface eth0 https://example.net/ip

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

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

השתמשו בתצוגת השרת כדי לאשר את העמית

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

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

הבחינו בין החלטת תכנון לדליפה

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

IPv6 ראוי לשורה משלו ברשימת הבדיקה. מנהרה שנושאת IPv4 בלבד משאירה למארח דו-ערימי נתיב שני שמיש, ויעד דו-ערימי יעדיף אותו — כולל DNS, אם הפותר נגיש דרך IPv6. השביתו IPv6 במתאם או אשרו שהמנהרה נושאת אותו לפני שאתם מתייחסים לתוצאת IPv4 כשלמה.

כשהבדיקות חולקות, המחלוקת בדרך כלל שמה את התקלה:

What you seeWhat it meansNext step
The route picks tun0 but the capture shows cleartext to 10.20.5.7Something bypassed the table: a bound app, a policy route or a session older than the tunnelReset the flow, check the app bind, check the ip rule list
The route picks eth0 for an internal nameThe name resolves to a public address, or the route was never installedCompare the resolved address with the routes the server pushes
The capture shows DNS to the LAN resolverResolver leak: data is tunneled, lookups are notPoint the resolver inside, or push it from the server
All four checks agree and one app still failsPath selection is fine; suspect MTU, a per-app proxy or the far endTest the same destination from a known-good client

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

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