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

התחילו מנקודת המבט של הלקוח

הלקוח בדוגמה זו נמצא במאגר ה-VPN 10.62.0.0/24 ומתחבר אל 10.62.0.1 בפורט 8080. הכתובת הזו שייכת לשער עצמו, ולכן החבילה מגיעה לליבה של השער ולא לעמית אחר. מאחורי השער נמצאת רשת ה-LAN 172.21.4.0/24. השער מחזיק את 172.21.4.10, וההתקן שבאמת מגיש HTTP הוא 172.21.4.40.

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

הגבילו את תרגום היעד במכוון

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

iptables -t nat -A PREROUTING -i tun0 -s 10.62.0.0/24 -d 10.62.0.1 -p tcp --dport 8080 -j DNAT --to-destination 172.21.4.40:80

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

תנו לגבול ההעברה להסכים

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

iptables -A FORWARD -i tun0 -o lan0 -d 172.21.4.40 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

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

ההתקן חייב להשיב בדרך כלשהי

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

ip route add 10.62.0.0/24 via 172.21.4.10 dev eth1
iptables -t nat -A POSTROUTING -s 10.62.0.0/24 -d 172.21.4.40 -o lan0 -p tcp --dport 80 -j SNAT --to-source 172.21.4.10

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

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

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

conntrack -L | grep 172.21.4.40
tcpdump -ni any 'port 8080 or port 80'

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

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