תעבורת Docker ו-VM מאחורי OpenVPN: לנתב או למספר מחדש?
מכולות ואורחים במארח שמריץ לקוח OpenVPN מאבדים את נתיב החזרה או מתנגשים בקידומת המנהרה. שלוש שאלות בוחרות את הפתרון.
המארח גולש דרך המנהרה והמכולה שלידו לא מגיעה לשום מקום. פרסום פורט ממכולה שמריצה לקוח VPN משלה גרוע יותר: הבקשה מגיעה והתשובה אף פעם לא יוצאת. שניהם החלטות ניתוב במארח, ו-Docker הוא רק השליח.
שלוש שאלות קובעות איזה משני המקרים יש לך, והן אורכות כדקה.
שני כשלים שנראים אותו דבר
הראשון הוא בעיית נתיב החזרה. הפורט שפורסם מתורגם אל המכולה, הבקשה מגיעה, והתשובה מנותבת דרך נתיב ברירת המחדל של המארח, שאותו לקוח OpenVPN הפנה אל tun0. התשובה יוצאת מכתובת שהעמית המרוחק אינו מצפה לה, והיא נזרקת. השני הוא התנגשות קידומות: גשר ברירת המחדל של Docker מחזיק ב-172.17.0.0/16 ומנהרה ארגונית דוחפת את אותו טווח.
האחד מתוקן בעזרת טבלת ניתוב, והשני על ידי מספור מחדש של גשר. עריכה לפני שאתה יודע מה הוא מה היא הדרך לשבור מכולה שעובדת.
החלט בשלוש שאלות
שאלה ראשונה: האם הכשל נעלם כשאתה עוצר את ה-VPN? אם הכול עובד כשהמנהרה כבויה, חשד בנתיב החזרה. שאלה שנייה: האם ip route show table all מציג את אותה קידומת פעמיים, פעם על גשר ופעם על tun0? זו ההתנגשות. שאלה שלישית: האם הכתובת שנפגעה היא מכולה, אורח NAT או אורח מגושר?
השאלה השלישית חשובה כי לכל אחד תיקון נכון אחר, והחלת תיקון המכולה על אורח libvirt מבזבזת ערב שלם.
ip route
ip route show table all | grep -E '172\.1[7-9]|10\.8'
docker network inspect bridge --format '{{.IPAM.Config}}'נתיב חזרה: טבלה עבור כתובת מקור אחת
כאשר תעבורת המכולה חייבת לצאת דרך הממשק הפיזי בעוד המארח עצמו משתמש במנהרה, ניתוב מבוסס מקור הוא השינוי הקטן ביותר. הוסף כלל שמתאים לכתובת המכולה ושלח אותו לטבלה ייעודית. שום דבר אחר במארח לא זז.
ip rule add from 172.22.0.3 lookup 10
ip route add default via 172.22.0.1 table 10כל מנות שמקורן בכתובת הזו בודקות תחילה את טבלה 10, וטבלה 10 שולחת אותן לשער הגשר במקום למנהרה.
אמת עם ip route get 1.1.1.1 from 172.22.0.3. התשובה חייבת לנקוב בממשק הגשר, לא ב-tun0. כללים שנוספים כך נעלמים באתחול, לכן שים אותם ביחידה או בהוק הרשת שמחזיק במכולה.
אותו דפוס עובד עבור מכולת WireGuard, שבה גם נתיב התשובה צריך כלל מפורש.
התנגשות קידומות: מספר מחדש את הגשר
טבלת ניתוב שולחת קידומת אחת למקום אחד. אם ה-VPN דוחף 172.17.0.0/16 בעוד הגשר של Docker כבר שם, המטריקה הנמוכה מנצחת: Docker מתקין את הנתיב המחובר שלו במטריקה 0, והנתיב הנדחף מגיע ב-50. אז המנהרה נראית שבורה בעוד Docker ממשיך לעבוד, או להפך, לפי סדר ההתקנה. מספר מחדש את הגשר במקום להיאבק במטריקה.
{
"bip": "10.200.0.1/24",
"default-address-pools": [{"base": "10.201.0.0/16", "size": 24}]
}הפעל מחדש את Docker לאחר השינוי וצור מחדש רשתות שנבנו עם המאגר הישן. שינוי המטריקה רק מעביר את ההתנגשות לאתחול הבא.
מכונות וירטואליות צריכות שוב תשובה אחרת
אורח libvirt ברשת NAT של ברירת המחדל יורש את הניתוב של המארח ומפסיק להגיע החוצה ברגע שהמנהרה של המארח מחזיקה בנתיב ברירת המחדל. העברת האורח להתקן מגושר או macvtap נותנת לו נתיב משלו ברשת הפיזית. ב-virt-manager הוסף חומרה, בחר Network, הגדר את המקור להתקן המארח macvtap, שמור על virtio כדגם, ואז השבת את ממשק ה-NAT הישן.
אורח macvtap בדרך כלל לא יכול להגיע למארח שלו. זו התנהגות צפויה ולא תקלה, והיא שייכת להערה שאתה משאיר.
עבור אורח שצריך רק את ה-LAN של המארח, ללקוח של הספק אולי יש את המתג החסר: עם Mullvad, mullvad lan set allow מחזיר את הנגישות המקומית בלי לגעת ב-libvirt. וכשמכולה חייבת להיות נגישה רק דרך המנהרה, קשר את הפורט שפורסם לכתובת המנהרה, -p 10.8.0.5:8080:8080, במקום לפרסם אותו בכל כתובת.