העברת פורט אל עמית WireGuard מאחורי NAT: DNAT יחד עם SNAT
DNAT מספק את הבקשה, אבל התשובה יוצאת מהכתובת הלא נכונה. הוסיפו כלל SNAT תואם ומקמו את שניהם לאחר שהמנהרה מוגדרת.
דפדפן מבקש https://203.0.113.10:8443, ה-proxy מקבל את החיבור, והשירות על עמית ה-WireGuard אינו עונה לעולם. כלל ה-DNAT עושה את עבודתו; התשובה היא החלק שנכשל. עקבו אחר החבילה דרך שתי ההמרות והכלל החסר הופך לברור. התיקון הוא הצהרת NAT אחת נוספת ב-hook הנכון, לא מנהרה חדשה.
עקבו אחר בקשה אחת מתחילה ועד סוף
הבקשה מגיעה לממשק הציבורי של ה-proxy עם הכתובת הציבורית של הלקוח כמקור וכתובת ה-proxy כיעד. ב-nat PREROUTING כלל ה-DNAT כותב מחדש את היעד לכתובת המנהרה של העמית, 10.90.0.2. לאחר מכן החלטת הניתוב שולחת את החבילה החוצה דרך wg0, ונתיב ההעברה הושלם.
בעמית, החבילה נושאת כעת את כתובת המקור הציבורית המקורית, מפני שדבר לא כתב אותה מחדש. השירות מקבל את החיבור ושולח את תשובתו לשער ברירת המחדל שלו, שהוא הנתב הביתי שלפני העמית. לנתב הזה אין מצב עבור זרימה שמעולם לא ראה, והוא או מפיל את החבילה או מתרגם אותה לכתובתו הציבורית, דבר שהלקוח לא יקבל.
האסימטריה היא הבעיה כולה: הבקשה עוברת דרך ה-proxy, והתשובה מנסה ללכת ישירות. מעקב החיבורים של ה-proxy עוזר רק אם התשובה חוזרת דרך ה-proxy, והיא לא יכולה לחזור לשם כל עוד כתובת המקור עדיין מצביעה על הלקוח המקורי.
הוסיפו את ההמרה החוזרת
כתבו מחדש את מקור הזרימה המועברת לכתובת המנהרה של ה-proxy לפני שהיא יוצאת אל העמית. אז השירות משיב אל 10.90.0.1, ה-proxy מקבל זאת, ומעקב החיבורים הופך את שתי ההמרות לפני שהחבילה חוזרת אל הלקוח.
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
iptables -t nat -A POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1כלל ה-POSTROUTING צר בכוונה: הוא מתאים ליעד המתורגם ולממשק המנהרה, ולכן אינו כותב מחדש תעבורה לא קשורה שיוצאת במקרה דרך wg0. כלל masquerade רחב היה מסתיר גם את כתובת הלקוח, אבל היה עושה זאת לכל זרימה והיה מקשה על ביקורת טבלת ה-NAT.
מקמו את הכללים במקום שבו קיימת המנהרה
כללים שמפנים לכתובת או לממשק המנהרה חייבים לרוץ לאחר ש-wg-quick הגדיר אותה. הממשק נוצר לפני PreUp, אבל כתובות, MTU, DNS ומסלולים מוחלים אחר כך, ו-PostUp רץ כשכל אלה במקומם. שימו את ההוספות ב-PostUp ואת המחיקות ב-PreDown.
PostUp = iptables -t nat -A PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
PostUp = iptables -t nat -A POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1
PreDown = iptables -t nat -D PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
PreDown = iptables -t nat -D POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1המחיקות חייבות להתאים להוספות טוקן אחר טוקן, כולל התאמות multiport והממשק. מחיקה ששונה בהתאמה אחת לא מסירה דבר, והחיבור הבא מוסיף עותק שני של הכלל. אחרי כמה חיבורים הטבלה מכילה כפילויות שקשה לייחס לשורת תצורה.
בדקו את התוצאה עם iptables -t nat -S לאחר חיבור מחדש. אם אותו כלל מופיע פעמיים, שורת ה-PreDown לא מתאימה והניקוי נכשל בשקט.
העברה, סינון וה-NAT האחר
הפעילו העברת IPv4 באופן קבוע, ואז התירו את הזרימה המועברת בטבלת הסינון. DNAT מתרחש לפני שרשרת ה-FORWARD, ולכן כלל הסינון מתאים ליעד המתורגם ולא לכתובת הציבורית. אם UFW מנהל את החומה, הביעו את ההיתר ככלל מסלול; כלל מארח רגיל אינו מכסה תעבורה מועברת.
שתי שכבות NAT אחרות עדיין יכולות לשבור את הנתיב גם כשכללי ה-proxy נכונים. בחיבור ביתי הכתובת הציבורית שייכת לנתב, ופתיחת הפורט בחומה שלו אינה זהה ליצירת רשומת העברת פורט ששולחת את הפורט הזה אל ה-proxy. פורט שנראה פתוח מבחוץ בזמן שדבר אינו עונה לרוב חסר בדיוק את המיפוי הזה.
ב-VPS עם NAT, הספק ממפה פורט ציבורי לכתובת פרטית. המיפוי חייב להתאים לפורט שאתם מפרסמים, ואי-התאמה נראית בדיוק כמו מנהרה שבורה. אשרו את המיפוי של הספק לפני שתשנו את תצורת WireGuard.
אמתו את נתיב החזרה וקבלו את המחיר
התחברו מרשת שאינה ה-LAN של ה-proxy, ואז בחנו את זוג ההמרות בזמן שהחיבור פתוח:
conntrack -L -p tcp --dport 8080
tcpdump -ni any tcp port 8080רשומת ה-conntrack אמורה להראות את ה-tuple המקורי, את ה-tuple המתורגם ואת כיוון התשובה. אם התשובה חסרה, העמית אינו שולח דרך המנהרה, מה שבדרך כלל אומר שכלל ה-SNAT לא הוחל או שהחומה של העמית עצמו הפילה את הזרימה.
הפעילו מחדש פעם אחת כדי להוכיח ש-PostUp מחיל שוב את הכללים, ואז עצרו את המנהרה ואשרו ש-PreDown הסיר אותם. כללים מתים ששורדים ניתוק הם הסיבה לכך ששינוי מאוחר מתנהג באופן בלתי צפוי.
לבסוף, קבלו את המחיר של SNAT. השירות רואה כל בקשה כאילו הגיעה מה-proxy, ולכן יומני גישה, מגבלות קצב לכל לקוח ורשימות כתובות מותרות כבר אינם מבדילים בין משתמשים. מקרה ה-hairpin זקוק להמרת מקור משלו עבור לקוחות ב-LAN של ה-proxy. אם העמית זקוק לכתובות לקוח אמיתיות, החלופה היא נתיב חזרה אל רשת הלקוח, שדורש יותר עבודה אבל שומר על המידע.