אתה מדמיין את שרת ה-VPN קורא את כתובת המחשב הנייד שלך מהחבילה וכותב אותה ליומן. מה שהוא קורא הוא מה שהקפיצה האחרונה של NAT שמה בכותרת החיצונית, ובטלפון שמשמש כנקודת גישה זה לרוב כתובת שמשותפת עם מאות מנויים אחרים. הכתובת של המכונה שלך עצמה 192.168.x.x לא חוצה את האינטרנט בכותרת הזו לעולם, וכתובת המנהרה ניתנת על ידי השרת אחרי שהחיבור כבר פעיל. לכן כשהלוג של השרת ו-ip addr במחשב הנייד לא תואמים, אף אחד מהם לא שגוי; הם מתארים שכבות שונות של הפעלה אחת.

שלוש כתובות, ורק אחת מהן ביומן

הבלבול נובע מכיווץ שלוש כתובות לאחת. לכל אחת בעלים אחר, היא חיה בכותרת אחרת ומגיעה לשרת בדרך אחרת.

AddressWho assigns itWhere it sitsVisible to the VPN server
Device address, e.g. 192.168.1.24Your router via DHCPOuter header, before translationNo, rewritten in place
Translated address and portRouter, ISP CGNAT, or bothOuter header, after translationYes, this is the tuple it logs
Tunnel address, e.g. 10.8.0.6The VPN server itselfInner header, after decapsulationYes, but it chose it

רק השורה האמצעית אינה ידועה בזמן החיבור. השרת כותב אותה לטבלת העמיתים, לקובץ המצב או ליומן הזרימה בהתאם לדמון: WireGuard קורא לה נקודת הקצה, קובץ מצב של OpenVPN מסמן אותה כ-Real Address, ו-strongSwan מדווח עליה כמארח המרוחק של ה-IKE_SA. הערך הזה מתרענן בכל פעם שמגיעה חבילה ממקור אחר, כך שהוא משתנה בלי שאיש יאתחל משהו.

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

למה הטאפל הנרשם משתנה בזמן שהמנהרה נשארת פעילה

תרגום כתובות הוא טבלה עם טיימר, לא קשר קבוע. נתב ביתי שומר על מיפוי ה-UDP שלו זמן מה אחרי החבילה האחרונה, שער של ספק ממחזר פורטים לפי לוח הזמנים שלו, וטלפון שעובר מ-Wi-Fi ל-LTE חוזר עם מקור אחר לגמרי. ברירות המחדל של conntrack בלינוקס הן אמת מידה שימושית כאן: nf_conntrack_udp_timeout הוא 30 שניות והגרסה לסטרימינג היא 120, כך שמנהרה שקטה יכולה לאבד את המיפוי הרבה לפני שהמשתמש שם לב.

המנהרה שורדת כי הפרוטוקול מאמת את העמית, לא את הכתובת. WireGuard הוא חסר מצב אחרי לחיצת היד, כך שכל חבילה מאומתת מעדכנת את נקודת הקצה השמורה והתקשרות מחדש נרפאת בחבילה הבאה; לכן קיים persistent-keepalive = 25, כדי לשמור על המיפוי חם בזמן חוסר פעילות. --float של OpenVPN עושה את אותה עבודה ומאפשר ללקוח מאומת להמשיך מכתובת ופורט חדשים. בגרסאות 2.4 ו-2.5 שבהן float כבוי כברירת מחדל, התקשרות מחדש מאפסת את ההפעלה והלקוח מתחבר שוב.

IPsec מגיע לשם עם יותר חלקים נעים. IKEv2 מבחין בתרגום על ידי השוואת ההאשים של המקור והיעד במטעני זיהוי NAT, עובר למעטפת UDP 4500 ועוקב אחרי keepalive לטאפל החדש. כשהחבילות keepalive חסומות, ה-SA נשאר פעיל על הנייר בעוד התעבורה בכיוון אחד נעצרת בשקט.

מה השרת יכול לייחס ומה לא

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

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

השוו את שני הקצוות במקום לנחש

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

ss -uapn 'dport = :51820'
ip -4 route get 203.0.113.10
wg show wg0 endpoints

אחר כך קראו את רשומת התרגום בנתב או בשער ה-CGNAT, ואת מה שבסופו של דבר מגיע לשרת:

conntrack -L -p udp --dport 51820
tcpdump -ni eth0 udp port 51820

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

איפה ההבדל שובר דברים

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

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

עברו על ארבע הבדיקות האלה לפי הסדר ועצרו בראשונה שנכשלת:

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

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

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