למה ה-VPN שלכם נופל כשה-Wi-Fi משתנה או כשה-Ethernet מתחבר
'SSID חדש, נדידה בין נקודות גישה וכבל שמתחבר שוברים מנהרה בשלושה מקומות שונים. בדקו את כתובת המקור, אחר כך את המסלול, ואחר כך את הפרוטוקול.'
שני דברים מדווחים כתקלה אחת: המחשב הנייד עבר לרשת Wi-Fi אחרת, או שכבל חובר בזמן ש-Wi-Fi נשאר פעיל. הלקוח עדיין אומר מחובר, הסמל נראה תקין, והמנהרה לא מעבירה דבר. מתחת לפני השטח רק שלושה חלקי מצב יכולים לזוז - החיבור, הכתובת המקומית, נתיב ברירת המחדל - וזה שזז קובע אם המנהרה תתאושש מעצמה או תזדקק לחיבור מחדש. אני בודק אותם בסדר הזה, כי שינוי הגדרות חשבון מעולם לא תיקן אף אחד מהם.
חיבור, כתובת ונתיב זזים בנפרד
נדידה בין נקודות גישה באותה רשת היא בדרך כלל אירוע L2. הרדיו מתחבר מחדש, הממשק שומר על הכתובת והשער שלו, ושום דבר שהמנהרה תלויה בו לא משתנה, ולכן הליכה במשרד גדול לפעמים עוברת בלי ששמים לב. הצטרפות ל-SSID אחר אינה כך: הממשק הישן עלול לרדת, DHCP נותן כתובת חדשה, שער חדש ומפענחים חדשים, והזרימה החיצונית שהמנהרה השתמשה בה מפסיקה להתקיים.
Ethernet מוסיף צורה שלישית. Wi-Fi לא נופל אף פעם, כך שאף אירוע חיבור לא נורה, אבל הממשק החוטי מופיע עם כתובת משלו ולעיתים קרובות זוכה בנתיב ברירת המחדל לפי מדד. המנהרה ממשיכה לרוץ בנתיב שאינו מועדף עוד, או שהלקוח משאיר את הסוקט מוצמד לרשת האלחוטית שבה התחיל. מהדפדפן שניהם נראים אותו דבר: העמודים נתקעים ברגע שהכבל נכנס.
אז השאלה הראשונה אינה אם ה-Wi-Fi השתנה. היא אם הכתובת שאליה אתם קשורים, או הנתיב לנקודת הקצה, השתנתה בזמן שהמנהרה הייתה פעילה.
הסוקט החיצוני מוצמד לכתובת שזה עתה נעלמה
כל מנהרה היא זרימה חיצונית: כתובת ופורט מקומיים שמדברים עם הכתובת והפורט של השרת. ב-Linux זהו סוקט UDP הקשור למקור הישן; כשממשק שמחזיק בכתובת מוסר, השליחות נכשלות ב-EADDRNOTAVAIL או יוצאות דרך הממשק החדש עם מקור שהשרת מעולם לא ראה.
הצד המרוחק שומר על ההצמדה שלו. SA של IKEv2 בלי MOBIKE מזוהה לפי זוג הכתובות, והפעלה של OpenVPN קשורה לכתובת העמית שלמדה, ומיפוי NAT שייך לכתובת הפרטית, לפורט ולכתובת הציבורית שיצרו אותו. עברו מאחורי NAT אחר וכל תשובה נשלחת למיפוי שכבר אינו קיים. שום דבר במכונה שלכם אינו מוגדר שגוי; החמישייה מצביעה לרשת שעזבתם.
קראו את המצב לפני שאתם מהרהרים בתיאוריה:
ss -unpמציג את הכתובת והפורט המקומיים שכל סוקט מנהרה באמת מחזיק.ip route get 203.0.113.10מדפיס את כתובת המקור וההתקן שהליבה הייתה משתמשת בהם עבור נקודת הקצה עכשיו.wg show wg0 endpoints,swanctl --list-sasאו יומן הלקוח מציג את כתובת העמית שהצד המרוחק חושב שהוא מדבר איתה.
אם כתובת הסוקט וחיפוש הנתיב אינם מסכימים, מצאתם את השבר, ואף שינוי באישורים לא ייגע בו.
מה כל פרוטוקול עושה עם כתובת מקור חדשה
לקוחות סופגים את השינוי בדרגות שונות, והטבלה היא מה שאני משווה מול תצורת הלקוח במקום לנחש מהתנהגות החיבור מחדש.
| Tunnel | Recovery behaviour | Failure signature |
|---|---|---|
| WireGuard | Updates the peer endpoint when an authenticated packet arrives from a new address; no handshake needed if traffic continues. | Handshake current, no return traffic; wg show still lists the old endpoint. |
| IKEv2/IPsec | MOBIKE (RFC 4555) moves the SA to the new address; without it the responder discards packets from an unknown source. | DPD or keepalive timeouts, then a full rekey or a dead SA. |
| OpenVPN over UDP | --float accepts a packet from a new source mid-session; otherwise the session stays tied to the original peer address. | Idle until ping-restart fires, then a visible reconnect. |
| OpenVPN over TCP | The tunnel is a byte stream, so a changed source address breaks it outright. | Immediate reset and a new connection attempt. |
כלל הנדידה של WireGuard עובד רק בכיוון אחד: הלקוח חייב לשלוח קודם מהכתובת החדשה. סוקט שעדיין קשור לממשק הישן לא עושה זאת לעולם, ולכן מנהרה יכולה להיראות חיה בזמן שטיימר לחיצת היד שלה מזדקן. תיאור הפרוטוקול מפרט במדויק את תנאי העדכון של נקודת הקצה, וכדאי לקרוא אותו לפני שמשנים תצורה.
MOBIKE מנוהל במשא ומתן, לא מניחים אותו. אם השרת לא מציע אותו, הלקוח חייב להקים מחדש, וזו עובדה שמאשרים מרשימת ה-SA או מהיומן ולא מסיקים מגלגל שמסתובב.
העדפת הנתיב קובעת את הדרך, לא סמל ה-Wi-Fi
כששני הממשקים למעלה, הליבה בוחרת לפי מדד ואורך קידומת. ip route show default מפרט את המועמדים ו־ip route get 203.0.113.10 מכריע את ההחלטה האמיתית, כולל כתובת המקור. נתיב ברירת מחדל חוטי במדד 100 ואלחוטי ב-600 פירושם שנקודת הקצה זזה ברגע שהכבל מתיישב, בעוד כל אפליקציה שפתחה סוקט קודם שומרת על המקור הישן שלה.
Windows עושה אותו דבר עם מדדי ממשק אוטומטיים, מוטים לפי מהירות החיבור. Get-NetRoute -DestinationPrefix 0.0.0.0/0 ממיין את המועמדים ו־Find-NetRoute -RemoteIPAddress 203.0.113.10 מחזיר את הממשק והמקור שהמחסנית הייתה בוחרת. לקוח שקושר את הסוקט החיצוני שלו לממשק אחד ממשיך להשתמש בו אחרי שהמדד מתהפך; זו החלטת קישור, לא תקלת ניתוב.
Android הופך את הפיצול לגלוי: ConnectivityManager מדווח על הרשתות הזמינות ועל ברירת מחדל נפרדת, ואפליקציית VPN שקושרת סוקט לאובייקט Network שומרת על הקישור עד שהיא קושרת מחדש. ב-macOS, scutil --nwi מדפיס את הממשק הראשי ואת הסדר שהמערכת הייתה משתמשת בו.
DNS, MTU ו-IPv6 זזים עם החיבור
חיבור חדש מביא מפענחים חדשים. עם systemd-resolved ה-DNS הוא לפי חיבור, resolvectl status מציג איזה חיבור עונה לשם, ורשת אורחים שמחלקת מפענח משלה יכולה להשאיר את ה-DNS שנדחף מהמנהרה ללא שימוש עד שהחיבור יועדף שוב. פורטל שבי מחמיר את המצב: הבקשה הראשונה ב-HTTPS נענית על ידי הפורטל ולא על ידי נקודת הקצה, והלקוח רושם שרת מת.
גם ה-MTU של הנתיב משתנה. Ethernet ו-Wi-Fi נושאים בדרך כלל 1500 בייט, PPPoE 1492, וחיבורים סלולריים לעיתים קרובות פחות. מנהרה שיורשת MTU קטן יותר נתקעת במנות גדולות בזמן שבקשות קטנות מצליחות, וזה נקרא כחיבור שבור למחצה. ping -M do -s 1472 203.0.113.10 שולח מנה של 1500 בייט עם DF מוגדר; שתיקה פירושה שהנתיב קטן ממה שהנחתם.
IPv6 הוא החצי השני. רשת שמחלקת קידומת חדשה משנה את המקור שלקוח דו-ערוצי היה משתמש בו, ומנהרה של v4 בלבד משאירה את תעבורת v6 מחוצה לה עד שהמדיניות תדביק. ip -6 route show default ו־ip -6 addr show עונים אם לחיבור החדש יש בכלל נתיב v6.
שחזרו את המעבר במקום לתאר אותו
בחרו בקשה אחת בלתי מזיקה והריצו את אותן שלוש פקודות משני צדי השינוי: ip -br addr, ip route show default, ip route get 203.0.113.10. אחר כך ראו אם המנהרה עדיין משדרת מנות - tcpdump -ni any udp port 51820 עבור WireGuard, הפורט המתאים לכל דבר אחר. מנות שיוצאות מהמקור הישן משמעותן בעיית קישור. מנות שיוצאות מהמקור החדש בלי תשובה משמעותן הצד המרוחק או ה-NAT שבדרך.
רשמו איזה אירוע חפף לתקלה הראשונה: ירידת חיבור, שינוי כתובת או שינוי בנתיב ברירת המחדל. אלה מצביעים על בעלים שונים - לקוח שצריך להיקשר מחדש, כתובת שצריך לרכוש מחדש, או נתיב ששייך לקובץ תצורה ולא לכלל עקיפה קבוע.
לפני שמכריזים שזה תוקן, אשרו שחסימת התעבורה הישירה עדיין מחזיקה במהלך הפער ושמות נפתרים דרך החיבור החדש. אם הלקוח מחזיק בנקודת הקצה הישנה אחרי המעבר, תקנו קודם את הגדרת הנדידה או float. אם הוא נודד כראוי ועדיין לא מקבל תשובה, הסתכלו בזהות העמית בשרת וב-NAT שבדרך, ושמרו את שני ההקשרים ברשת בכתוב כדי שהאדם הבא יוכל להשוות ביניהם.