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

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

בדיקה 1: המארח צריך חיבור שהוא יכול להקצות לו כתובת

המארח חייב להחזיק ממשק שנמצא באותו קידומת כמו המתאם השני של האורח. host-only ב-VirtualBox, host-only או VMnet מותאם ב-VMware Workstation, גשר פנימי או התקן tap ב-QEMU/KVM, ומתג Internal ב-Hyper-V כולם מתאימים. אורח 192.168.56.2, מארח 192.168.56.1, קידומת 192.168.56.0/24 היא הפריסה שאני משתמש בה במעבדות.

רשת QEMU במצב משתמש (-netdev user, ה-backend ברירת המחדל SLIRP) ו-NAT של VirtualBox נכשלים בבדיקה הזו לחלוטין. החבילות של האורח מגיעות לתהליך פרוקסי על המארח, כך שהמארח אף פעם לא רואה התקן שנושא את הכתובות של האורח ואין לו למה לכוון נתיב. ה-Default Switch של Hyper-V הוא אותו סיפור. אם ping 192.168.56.2 מהמארח נכשל, עצור: שום נתיב שיתווסף מאוחר יותר לא יתקן את זה.

בדיקה 2: האורח מעביר ומתרגם

חבילות מהמארח מגיעות עם כתובת מקור של רשת host-only ויעד פנימי, ולכן האורח חייב להעביר אותן ואז להסתיר אותן מאחורי כתובת המנהרה שלו. באורח Linux משמעות הדבר היא העברה, זוג FORWARD accept ו-source NAT לכיוון המנהרה:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE

כלל MASQUERADE הוא החלק שאנשים משמיטים. נתבים ארגוניים כמעט ולא יודעים ש-192.168.56.0/24 קיים; עם הכלל, שרתים פנימיים רואים את כתובת המנהרה של האורח ועונים לה, והתשובה מוצאת את דרכה חזרה לאורח.

אורח Windows מסורבל יותר. IPEnableRouter=1 תחת SYSTEM\CurrentControlSet\Services\Tcpip\Parameters מפעיל העברה בלי תרגום, ולכן זה עובד רק במקום שבו הניתוב הארגוני כבר מצביע חזרה לקידומת ה-host-only שלך. שיתוף חיבור לאינטרנט מתרגם, אבל הוא ממספר מחדש את המתאם המשותף ל-192.168.137.1, לכן קרא את הכתובת שהוא באמת קיבל לפני שאתה כותב נתיבי מארח.

בדיקה 3: נתיבי המארח מציינים את האורח, לא את המנהרה

שלח דרך האורח רק את הקידומות שהמארח צריך. ב-Linux נתיב אחד לכל קידומת מספיק והוא מתהפך בצורה נקייה:

sudo ip route add 10.20.0.0/16 via 192.168.56.2
ip route get 10.20.30.40

ב-Windows המקבילה היא route add 10.20.0.0 mask 255.255.0.0 192.168.56.2. השאר בחוץ את -p בזמן שאתה עדיין בודק, כדי שנתיב רע ימות באתחול, והוסף אותו כשה-path עובד. אל תסיר את נתיב ברירת המחדל של המארח אלא אם כל יישום במארח אמור להשתמש במנהרה; אם מנהרה מלאה היא באמת הדרישה, הוסף את שני נתיבי /1 ושמור על הנתיב הישיר לרשת ההיפרוויזר:

sudo ip route add 0.0.0.0/1 via 192.168.56.2
sudo ip route add 128.0.0.0/1 via 192.168.56.2

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

בדיקה 4: DNS הולך אחרי הנתיב, לא אחרי ברירת המחדל של המנהרה

נתיבים מזיזים חבילות; הפותר מחליט אילו שמות מייצרים חבילות. הגבל את הפותר הארגוני לאזור הארגוני במקום להחליף את הפותר של המארח, והפנה אותו לשרת DNS שהנתיב החדש כבר מגיע אליו. עם systemd-resolved במארח:

resolvectl dns eth1 10.20.0.53
resolvectl domain eth1 '~corp.example.com'

ב-Windows רשומה בטבלת מדיניות פתרון השמות עושה את אותה עבודה: Add-DnsClientNrptRule -Namespace ".corp.example.com" -NameServers 10.20.0.53. אם האורח מריץ פותר משלו על כתובת ה-host-only, השתמש בכתובת הזו במקום, אבל רק אחרי שאישרת שהוא עונה על 192.168.56.2 ולא על loopback.

אחר כך בדוק את ה-MTU לפני שאתה מאשים את DNS בעמודים איטיים. ממשק המנהרה קטן מממשק 1500 הבתים של המארח, ולכן מארח ששולח סגמנטים בגודל מלא עם סיבית DF דלוקה רואה אותם נזרקים איפשהו בתוך האורח. הסימפטום הקלאסי הוא ping שעובד ואפליקציית ווב פנימית שנתקעת אחרי לחיצת היד של TLS. הדק את ה-MSS בנתיב ההעברה של האורח:

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

בדיקה 5: אמת משני הקצוות

מהמארח, traceroute או tracert לכתובת פנימית אמורים להראות את 192.168.56.2 כקפיצה הראשונה, לא את השער הפיזי. באורח, צפה באותו ניסיון יוצא: tcpdump -ni any host 10.20.30.40 מראה את הבקשה המועברת בצד ה-host-only ואת המתורגמת על המנהרה. בקשה שיוצאת, חוזרת ובכל זאת משאירה את המארח שקט מצביעה על נתיב החזרה.

שני כשלים מסבירים את רוב זה. או שהמנהרה של האורח לא נושאת נתיב חזרה לקידומת ה-host-only כי חסר כלל ה-NAT, או שנתיב המארח מצביע לכתובת שלאורח אין יותר אחרי אתחול. קרא שוב את הכתובות עם ip -br addr ו-ip route get במקום לסמוך על הערות מהפעם הקודמת.

בדיקה 6: הפוך את זה לשורד אתחול ושדרוג היפרוויזר

החזק את שני החצאים באופן קבוע: תצורת נתיבים של netplan או NetworkManager במארח, route add ... -p ב-Windows, ו-net.ipv4.ip_forward=1 בתוך /etc/sysctl.d/ ועוד סט כללי חומת אש שנטען מחדש באורח. צלם snapshot של האורח ברגע שהתצורה מאומתת, לפני שעדכון הלקוח הארגוני הבא מגיע.

רשתות host-only מקבלות מספור מחדש כשהיפרוויזר יוצר מחדש את המתאמים שלו, וזה מבטל בשקט כל נתיב וכלל NAT שנבנו על 192.168.56.0/24. אחרי שדרוג, הרץ שוב את שלוש הבדיקות הראשונות לפי הסדר; זה עולה דקה ותופס את המקרה שבו למארח עדיין יש את הנתיב שלו בעוד האורח עבר לתת-רשת חדשה.

IPv6 צריך מעבר משלו. כללי ip6tables, רשומות AAAA ומשפחת נתיבי מארח שנייה לא הולכות אחרי הגדרת IPv4, ושירות ארגוני שנגיש דרך IPv6 ייראה שבור לתמיד בזמן ש-IPv4 עובד.

עבר או לא, לפי הסדר: המארח יכול לעשות פינג לכתובת ה-host-only של האורח; האורח מעביר ועושה MASQUERADE לכיוון המנהרה; ip route get מחזיר את האורח כשער לקידומת הפנימית; שמות ארגוניים נפתרים דרך הפותר המוגבל; traceroute מראה את האורח ראשון; ואותן שש תשובות שורדות אתחול.

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