שער ציבורי כבר מריץ WireGuard על UDP 51820, SSH על 22 ואפליקציה אחת שחייבת להיות נגישה מהאינטרנט. הכלל המפתה מעביר כל פורט אל ה-peer ומכריז שהעבודה נגמרה. בשער WireGuard כלל כזה עלול ללכוד את התעבורה של המנהרה עצמה ולנעול אתכם מחוץ למכונה שמסיימת אותה. פרסום הוא החלטת ניתוב עם חריגה למישור הבקרה, ולא שורת DNAT אחת.

כניסה ציבורית או כניסה דרך המנהרה: בחרו אחת

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

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

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

פורט אחד פנימה, backend אחד החוצה

השתמשו בפורט ציבורי אחד ובשירות backend אחד. בדוגמה הזו eth0 נושא את הכתובת הציבורית 198.51.100.20, כתובת המנהרה של השער היא 10.200.0.1, וה-peer מריץ את האפליקציה על 10.200.0.7. ה-TCP הציבורי 9443 ממופה ל-TCP 8443 של ה-peer:

iptables -t nat -A PREROUTING -i eth0 -d 198.51.100.20 -p tcp --dport 9443 -j DNAT --to-destination 10.200.0.7:8443
iptables -t nat -A POSTROUTING -o wg0 -d 10.200.0.7 -p tcp --dport 8443 -m conntrack --ctorigdst 198.51.100.20 --ctorigdstport 9443 -j SNAT --to-source 10.200.0.1

כלל ה-SNAT מתאים ל-backend המתורגם וליעד הציבורי המקורי, ולכן חיבור אחר לאותו שירות backend נשאר מחוץ למיפוי הזה. הוא גם מסתיר את כתובת המבקר מה-peer, וזו הפשרה שהופכת חזרה מנותבת עם שימור מקור לתכנון נפרד. הפניה להרחבות iptables מתעדת את שתי המטרות ואת אפשרויות ההתאמה שלהן.

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

ה-peer חייב לקבל את חיבור השירות מכתובת המנהרה של השער ולהחזיר את התגובה דרך המנהרה. ה-AllowedIPs שלו חייב לאשר את המקור שהוא באמת מקבל, שבתחת לתרגום מקור הוא כתובת המנהרה של השער, ורשומת 0.0.0.0/0 רחבה בכל peer אינה נדרשת לתכנון הזה. מה שמפיל את תעבורת החזרה הוא peer שהרשימה שלו משמיטה את הכתובת הזו, או תכנון עם שימור מקור שמעביר במקום זאת את כתובת המבקר עצמו, לכן בדקו את המקור שה-peer באמת רואה, ולא את זה שבכלל שלכם.

השאירו את המאזינים של השער מחוץ לכלל

החליפו את התאמת הפורט בכלל שמכסה כל יעד TCP ו-UDP, וה-socket של WireGuard של השער נופל בתוכו. תרגום היעד מתרחש לפני שהמכונה מחליטה שהחבילה מקומית, ולכן UDP 51820 יכול להגיע ל-peer במקום לתהליך שמחזיק כל חיבור peer. הכלל נטען בהצלחה והמנהרה מתה, וזו תקלה שקשה לקרוא מצד ה-peer.

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

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

העברה רחבה של TCP ו-UDP אינה גם כל הפרוטוקולים. ICMP, IPv6, משוב path-MTU ותעבורת ה-VPN החיצונית זקוקים למדיניות משלהם, וכלל שמכסה TCP ו-UDP משאיר את המקרים האלה לשרשרת ברירת המחדל.

בחרו את המודל לפני שכותבים כללים

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

ModelWhat it protectsCostUse when
Narrow port forwardEvery other listener, including the VPNOne rule per serviceFew services, stable ports
Catch-all with reserved portsPorts named in the exception listRule order becomes criticalMany services and disciplined review
Separate public addressControl address fully isolatedProvider must supply the addressHigh-value publication
VPN-only accessNo public entry at allVisitors need the tunnelAdmin interfaces and internal tools

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

הוכיחו גם את הפרסום וגם את נתיב הבקרה

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

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

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