होस्ट टनल से ब्राउज़ करता है और उसके पास का कंटेनर कहीं नहीं पहुँचता। जिस कंटेनर में अपना 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 नहीं। इस तरह जोड़े गए नियम रीबूट पर मिट जाते हैं, इसलिए उन्हें उस unit या नेटवर्क हुक में रखें जो कंटेनर का मालिक है।

यही पैटर्न 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 पुनः आरंभ करें और पुराने पूल से बने नेटवर्क फिर से बनाएँ। इसके बजाय मीट्रिक बदलना केवल टकराव को अगले बूट पर सरका देता है।

VM को फिर से दूसरा जवाब चाहिए

डिफ़ॉल्ट NAT नेटवर्क पर libvirt अतिथि होस्ट की रूटिंग विरासत में लेता है और होस्ट की टनल के डिफ़ॉल्ट रूट का मालिक बनते ही बाहर पहुँचना बंद कर देता है। अतिथि को ब्रिज या macvtap डिवाइस पर ले जाने से उसे भौतिक नेटवर्क पर अपना रास्ता मिलता है। virt-manager में हार्डवेयर जोड़ें, Network चुनें, स्रोत को macvtap होस्ट डिवाइस पर सेट करें, मॉडल के रूप में virtio रखें, फिर पुराना NAT इंटरफ़ेस निष्क्रिय करें।

macvtap अतिथि आमतौर पर अपने ही होस्ट तक नहीं पहुँच सकता। यह अपेक्षित व्यवहार है, खराबी नहीं, और यह उस नोट में होना चाहिए जो आप छोड़ते हैं।

जिस अतिथि को केवल होस्ट का LAN चाहिए, उसके लिए विक्रेता के क्लाइंट में वह गायब स्विच हो सकता है: Mullvad के साथ mullvad lan set allow libvirt को छुए बिना स्थानीय पहुँच बहाल करता है। और जब कंटेनर केवल टनल से ही पहुँच योग्य होना चाहिए, तो प्रकाशित पोर्ट को टनल पते से बाँधें, -p 10.8.0.5:8080:8080, हर पते पर प्रकाशित करने के बजाय।

संबंधित लेख