SNAT מול DNAT מול Masquerade: מה כל כלל NAT ב-VPN עושה
NAT מקור כותב מחדש מאיפה נראית הזרימה מגיעה; NAT יעד כותב מחדש לאן היא הולכת. Masquerade הוא NAT מקור עם כתובת מושאלת.
הניחו לכידה משני צדי שער VPN וזרימה אחת יכולה להראות ארבע כתובות שונות. NAT מקור כותב מחדש מאיפה החבילה טוענת שהיא מגיעה; NAT יעד כותב מחדש לאן היא הולכת. Masquerade אינו כיוון שלישי, הוא כלל NAT מקור שלוקח את כתובתו מהממשק היוצא במקום מערך קבוע. תנו שם למי מהשלושה אתם באמת צריכים ורוב הכרטיסים „ה-VPN שבור” מתכווצים לשאלה על נתיב החזרה.
מה כל כלל כותב מחדש
NAT מקור, שנכתב בדרך כלל SNAT, משנה את כתובת המקור של זרימה כשהיא יוצאת מנתב או משער. השירות המקבל משיב לכתובת המתורגמת, והקופסה שמתרגמת הופכת את השינוי בחזרה בעזרת המצב ששמרה לאותו חיבור. ב-Linux המצב הזה חי ב-conntrack, ולכן conntrack -L מדפיס את הזוגות המקוריים והמשיבים זה לצד זה.
NAT יעד, DNAT, משנה במקום זאת את היעד. חבילה שנשלחה לכתובת ציבורית ב-UDP 51820 ניתנת לכתיבה מחדש אל שרת WireGuard פנימי ב-10.8.0.2:51820. כך נתב ביתי או מאזן עומסים בענן מפרסם מאזין VPN, וזה לא אומר דבר על מה שהמנהרה עשויה לשאת אחר כך.
Masquerade שייך למשפחת SNAT. הכלל אינו נוקב בכתובת; הוא משתמש בכל כתובת שיש לממשק היוצא כשהחבילה יוצאת. Linux נותן לו יעד משלו, וזה הבחירה הרגילה בממשק WAN שמקבל את כתובתו מ-DHCP או מ-PPPoE.
היכן חי המיפוי קובע את הכשל
רשמו את הזוג בכל גבול: לפני המנהרה, בתוכה ועל הממשק הציבורי. לכידה בתוך המנהרה שונה כדין מזו שמחוצה לה, ומי שמשווה בין השתיים בלי לדעת היכן מתרחש התרגום ירדוף אחרי המארח הלא נכון.
תעבורת החזרה חייבת לעבור דרך ההתקן שמחזיק את המיפוי. אם התשובה יוצאת בנתיב אחר, בקישור עליון שני, בנתיב מדיניות או אצל ספק שמעולם לא שמע על הטווח הפרטי שלכם, התרגום ההפוך עם מצב לא קורה והלקוח רואה תעבורה חד-כיוונית. הוספת עוד NAT מקור כמעט אינה מתקנת נתיב חזרה חסר; היא יכולה להסתיר את התסמין בזרימה אחת ובמקביל לשבור מדיניות מבוססת כתובות בכל מקום אחר.
הטעות הנפוצה האחרת היא לצפות שמנהרה תיצור יכולת ניתוב. לקוח פרטי שחבילותיו יוצאות לאינטרנט זקוק לסידור יציאה תקף: נתיב ברירת מחדל, שער שמעביר הלאה ובדרך כלל תרגום מקור לכתובת ציבורית. הצפנה לבדה אינה הופכת כתובת פרטית לנגישה.
Masquerade או SNAT מפורש
השוו ביניהם לפי מה שהם מבטיחים. Masquerade בוחר את כתובת היציאה, SNAT מפורש מצמיד אותה. בשער עם כתובת ציבורית יציבה, הצמדה נותנת ליומנים ולרשימות ההיתר של השותפים ערך אחד צפוי. בקישור WAN דינמי, כתובת SNAT מוצמדת נהפכת שגויה ברגע שהחכירה משתנה, וזה בדיוק המקרה שלשמו נבנה Masquerade.
ההיקף חשוב לא פחות מהבחירה. כלל Masquerade שמתאים לכל חבילה שיוצאת מהשער, בלי הגבלת מקור או יעד, מתרגם גם תעבורה שרציתם להשאיר שלמה, כולל תעבורה לרשתות פרטיות אחרות. הגבילו את הכלל לטווח הלקוחות, ליעד המיועד ולממשק.
IPsec מבוסס מדיניות הוא המקום שבו זה נושך הכי חזק. מדריך ההעברה של strongSwan עובר על הפעלת העברת IP ועל הוספת כלל SNAT מקור ללקוחות, ואותה תיעוד מכסה גם הוצאת תעבורה שחייבת לשמור על כתובתה המקורית. תרגמו מקור לפני שמדיניות האבטחה מתאימה לו והמנהרה יכולה לעלות בעוד התעבורה עדיין נופלת, כי החבילה כבר אינה נראית כמו הבורר שנדון.
החליטו גם מה הקצה הרחוק צריך לראות. אחרי התרגום שירות רואה את השער, לא את הלקוח הבודד. זה מפשט את ניתוב החזרה ובמקביל משטח יומנים ומבטל רשימות היתר לכל לקוח. אם שמירה על כתובות הלקוחות חשובה, תכננו נתיב חזרה מנותב במקום להסתירן כדי שבדיקה תעבור.
לקרוא את הכללים בשער Linux
שער גישה מרחוק עם לקוחות ב-10.8.0.0/24 וממשק WAN בשם eth0 זקוק להעברה מופעלת ולמדיניות סינון שמתירה את הזרימה, לפני שכלל NAT כלשהו יכול לעזור. גרסת iptables מחזיקה את שני הכיוונים בטבלת nat:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 51820 \
-j DNAT --to-destination 10.8.0.2:51820
צורת nftables משתמשת באותם שני ווי hooks עם ממשק בשם ושרשרת מפורשת:
nft add rule ip nat postrouting ip saddr 10.8.0.0/24 oifname "eth0" masquerade
nft add rule ip nat prerouting iifname "eth0" udp dport 51820 dnat to 10.8.0.2:51820
שני הקטעים מניחים ששרשרת הסינון כבר מקבלת את הזרימה המועברת. NAT אינו כלל היתר, וחבילה מתורגמת כהלכה עדיין עלולה להיזרק טבלה אחת לאחר מכן. אשרו את המיפוי החי עם conntrack -L, אשרו מה טעון עם nft list ruleset או iptables-save -t nat, ואז לכדו בשני הממשקים כדי לראות שהכתובת באמת משתנה.
מצבי כשל שנראים כמו כלל רע
תעבורת סיכת ראש היא הקלאסיקה. לקוח פנימי שמגיע לשרת פנימי דרך הכתובת הציבורית של השרת זקוק ל-DNAT בדרך פנימה ולתרגום מקור בדרך חזרה החוצה, אחרת השרת משיב ישירות ללקוח והתשובה נדחית. התיקון הוא כלל שני וצר יותר למקרה הזה של פנימי אל ציבורי, לא כלל Masquerade רחב יותר להכול.
תרגום כפול הוא השקט. לקוח שכבר נמצא מאחורי NAT ברמת ספק מגיע לשער שלכם עם כתובת שאי אפשר לנתב חזרה, ולכן אתם מתרגמים שוב. זה עובד, אבל היומנים נושאים כעת שתי קפיצות של מיעון פרטי וכל חקירה זקוקה לשני המיפויים. IPsec מבוסס מדיניות מוסיף סיבוב שלישי: תרגמו לפני התאמת המדיניות ותקבלו SA שעלה בלי שתעבורה עוברת, מה שנקרא כמו באג בחומת האש ולא ב-NAT.
ואז יש את הבדיקה שעוברת ואת הפריסה שנכשלת. הרצת פקודת NAT ביד מוכיחה את המנגנון, לא את התצורה. כלל שנוסף בזמן ריצה נעלם באתחול או באירוע הממשק הבא, וכלל Masquerade הקשור לממשק שמספרו משתנה יכול לשנות בשקט את הכתובת שהקצה הרחוק רואה. שימו את הכלל בתצורת חומת האש שבבעלותו ובדקו שוב אחרי התחברות מחדש.
רשימת בדיקה לפני שמירת הכלל
תנו שם לכיוון קודם: מקור, יעד או שניהם. אחר כך זהו מי חייב להחזיק במצב — השער, הנתב שמעל או עמית ה-IPsec — ואשרו שנתיב התשובה חוזר דרכו. הגבילו את הכלל לטווח הלקוחות, ליעד ולממשק שאתם באמת מתכוונים אליהם, והחליטו מראש אם הקצה הרחוק צריך לראות את השער או את כתובת הלקוח המקורית.
בדקו מלקוח, לא מהשער. דפדפן על השער עצמו יכול לעקוף לגמרי את כלל תרגום הלקוחות, ולכן עמוד שעובד שם אינו מוכיח דבר על המנהרה. שלחו בקשה אחת שמקורה בלקוח, עקבו אחרי המונים ואחרי טבלת conntrack, וחזרו על כך אחרי התחברות מחדש של המנהרה ושינוי כתובת WAN אם אחד מהשניים אפשרי במקום שבו אתם עובדים.