אפליקציה בתוך מרחב שמות VPN אינה נגישה מה-LAN
מרחב שמות רשת נותן לתוכנית אחת מנהר משלו וממשק לולאה משלו. פרסמו רק את הפורט שלו בעזרת קפיצת socat או זוג veth במקום המארח.
השירות שלכם עובד במכונה, המנהר פעיל, והדפדפן על השולחן שלכם עדיין ממתין לתשובה. שום דבר לא שבור במובן הרגיל: היישום מאזין בתוך מרחב שמות רשת, והמחסנית הזו בלתי נראית ל-LAN. ממשק הלולאה שלו שייך למרחב השמות, ולכן ללקוח במכונה אחרת אין כתובת שמגיעה לפורט. קפיצה מכוונת אחת, או זוג veth אחד, מתקנת זאת בלי להזיז את שאר המארח.
מדוע דבר אינו עונה על כתובת ה-LAN
מרחב שמות הוא מחסנית רשת שלמה: ממשקים, מסלולים, כללי חומת אש וממשק לולאה פרטי. תהליך שהופעל דרך ip netns exec רואה את המחסנית הזו ושום דבר אחר, ולכן הכתובת שאליה הוא נקשר נפתרת רק בתוך מרחב השמות. ה-127.0.0.1 של המארח עצמו הוא ממשק לולאה אחר לגמרי.
לכן curl במארח נכשל בעוד אותה פקודה בתוך מרחב השמות מצליחה. היישום בריא; הכתובת פשוט אינה קיימת במחסנית של המארח.
פרסמו פורט אחד בעזרת קפיצת socat
socat מגשר בין שתי המחסניות במרחב המשתמש, וזה מספיק כאשר פורט TCP יחיד צריך לעבור. צד המארח מאזין ב-LAN, ועבור כל חיבור שהתקבל מפעיל socat שני בתוך מרחב השמות שמתחבר לממשק הלולאה של היישום. התהליך הפנימי מגיע ליישום בדיוק כפי שלקוח מקומי היה עושה. שום דבר בניתוב מרחב השמות לא משתנה, ולכן היישום ממשיך להשתמש במנהר כיציאה היחידה שלו.
socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork
התהליך החיצוני זקוק ל-root או ליכולת להיכנס למרחב השמות. אם ה-VPN נופל, היישום מאבד את הנתיב שלו והפורט שפורסם נכשל סגור, וזו ההתנהגות שאתם רוצים מכלא.
השתמשו בזוג veth כאשר עובר יותר מפורט אחד
זוג veth הוא התשובה הנכונה כאשר כמה פורטים או פרוטוקולים חייבים לעבור, או כאשר מארחים אחרים צריכים ליזום חיבורים. קצה אחד נשאר במארח, השני עובר למרחב השמות, ו-/30 קטן נותן לשני הצדדים כתובת יציבה. אחר כך מסלול מארח שולח את כתובת מרחב השמות דרך הזוג.
ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpn
ip addr add 10.77.0.1/30 dev veth0
ip link set veth0 up
ip netns exec vpn ip addr add 10.77.0.2/30 dev veth1
ip netns exec vpn ip link set veth1 up
אל תוסיפו מסלול ברירת מחדל דרך המארח אלא אם אתם מתכוונים לשבור את הכלא. המנהר צריך להישאר היציאה, ולכן דרך הזוג נגישה רק כתובת השירות שפורסמה. תנו למרחב השמות גם קובץ מאתר משלו, כי ip netns exec קורא את /etc/netns/vpn/resolv.conf ובלעדיו פתרון השמות בתוך הכלא ריק.
בדקו ממכונה אחרת, לא מהמארח
הריצו את הבדיקה ממכונה שנייה, כי המארח יכול להגיע למאזין מקומי בדרכים שאומרות דבר על ה-LAN. בדקו תחילה למה היישום באמת נקשר בתוך מרחב השמות, ואז התחברו לכתובת שפורסמה מבחוץ. קישור לכל כתובת שם אינו מרחיב את הכלא, כי תו הכלל עדיין שייך למרחב השמות וה-LAN אינו יכול לראות אותו.
ip netns exec vpn ss -lntp
אם החיבור מהמארח עובד והחיבור מה-LAN לא, החלק החסר הוא הקפיצה או המסלול, לא כתובת הקישור. הפעילו את OpenVPN בתוך מרחב השמות במקום להעביר לשם התקן tun פעיל, מכיוון שהעברת הממשק מכבה אותו ועלולה למחוק מסלולים שלא תוכלו לתקן מבחוץ לאחר מכן. השאירו את פקודות השחזור בקונסולה, לא בתוך הכלא.