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

המנהרה היא לא מה שנשבר

שני הקצוות יושבים על טווחים פרטיים, שזה המקרה הרגיל ולא תצורה שגויה. כתובת כמו 10.8.0.6 אמיתית בתוך המנהרה ואינה קיימת בשום מקום אחר, ולכן ל-LAN אין סיבה לשלוח לשם דבר. לפני שנוגעים בניתוב, ודאו שהשירות בכלל נגיש בתוך המנהרה: בלקוח, ss -ltn מראה אם המאזין נקשר ל-127.0.0.1, לממשק ה-LAN או לכתובת המנהרה. תהליך שנקשר רק ל-loopback לא עונה לאיש מלבד עצמו, ושום נתיב, DNAT או העברת פורט לא משנה את זה.

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

צורת הנתיב: אמרו ל-LAN איפה הבריכה

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

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

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

push "route 192.168.1.0 255.255.255.0"

עבור תת-רשת שיושבת מאחורי לקוח אחד ולא מאחורי השרת, השרת צריך גם נתיב מערכת וגם רשומת iroute בקובץ של אותו לקוח תחת client-config-dir. בלי iroute, OpenVPN יודע שהקידומת קיימת ואין לו מושג איזה לקוח מחזיק בה: מנות מגיעות ולתהליך אין מה להתאים להן.

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

צורת NAT: DNAT פנימה, ושורת ה-SNAT שכולם מדלגים עליה

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

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

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

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

למה כלל שנראה נכון עדיין מפיל את המנה

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

  • סדר השרשראות. iptables -I מכניס בראש ו--A מוסיף בסוף, ולכן כלל מתיר או חוסם מוקדם יותר הוא שמכריע ראשון.
  • שרשרת שגויה. תעבורה שמופנית לנתב עצמו עוברת ב-INPUT, ותעבורה מועברת אף פעם לא נוגעת בה. פרסום שירות אחד יכול לדרוש כללים בשתיהן.
  • דגלי כיוון. -i tun0 מתאים לתעבורה שמגיעה מהלקוחות ו--o tun0 לתעבורה שיוצאת אליהם. REJECT עם הדגל הלא נכון חוסם משהו שלא התכוונתם אליו.
  • הגבלת מקור. העברה שמקבלת כתובת לקוח אחת עובדת מאותו לקוח ומפילה כל מקור אחר בלי מילה.

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

ההעברה המקומית, כששום דבר ב-LAN לא יכול להשתנות

העברה מקומית של SSH עוקפת את כל השאלה. היא לא צריכה נתיב ב-LAN, לא שיתוף פעולה מחומת האש של הלקוח, ולא פורט שמפורסם במקום כלשהו:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

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

אמתו את שני הכיוונים לפני שמוסיפים כלל נוסף

תרגום משאיר עקבות, וקריאה שלהן עדיפה על ניחוש. במארח ה-VPN, conntrack -L מראה אם התרגום קרה בכלל, iptables -t nat -L -n -v מראה אם המונים זזו, ו-tcpdump -ni any port 3000 מראה איזו כתובת מקור באמת הגיעה. בלקוח, ss -ltn מאשר שהמאזין נמצא על כתובת שהמנהרה יכולה להגיע אליה.

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

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