होस्ट VPN लाई बेवास्ता गर्ने Docker र WSL ट्राफिक सुधार्नुहोस्
कन्टेनर र WSL आफ्नै रुट, रिजोल्भर र फर्वार्ड मार्ग राख्छन्, त्यसैले काम गर्ने होस्ट टनेलले तिनीहरूलाई पुरानो DNS वा आउटलेट बिना छोड्छ। प्रत्येक तह सुधार्नुहोस्।
यो वसन्तमा मैले एउटा बिहानको धेरैजसो समय एउटै आन्तरिक नाम पनि समाधान गर्न नसक्ने कन्टेनरको पछि लागेर बिताएँ, जबकि छेउको ब्राउजर कुनै गुनासो बिना विकी खोलिरहेको थियो। टनेल माथि थियो, ब्राउजरले त्यो प्रमाणित गरिरहेको थियो, र कन्टेनर अर्को रुट तालिका र अर्को रिजोल्भर भएको अर्को नेटवर्क नामस्थानमा थियो. अब मैले जाँच्ने क्रम यो हो: पहिले रुट तालिका, दोस्रो नाम समाधान, तेस्रो फर्वार्डिङ र अन्तमा होस्ट प्लेटफर्म। पहिले नै असफल हुने पहिलो चरणमा रोकिनुहोस्, किनकि स्ट्याकमा तल नियम थप्दा सीमा सार्नुको सट्टा लुकाउँछ।
नियम परिवर्तन गर्नु अघि तीनै रुट तालिका तुलना गर्नुहोस्
Docker को पूर्वनिर्धारित ब्रिजमा रहेको कन्टेनरसँग docker0 गेटवेतिर जाने एउटा पूर्वनिर्धारित रुट छ, र tun0 अवस्थित छ भन्ने थाहा छैन। होस्टमा tun0, VPN ले धकेलेका रुटहरू, र सायद तपाईंले अपेक्षा गरेभन्दा फरक इन्टरफेसबाट परीक्षण ट्राफिक पठाउने नीति नियम पनि छ। WSL ले आफ्नै भर्चुअल एडाप्टरको पछाडि तेस्रो तालिका थप्छ। कुनै पनि सम्पादन गर्नु अघि तीनै प्रिन्ट गर्नुहोस्।
| Context | Command | What a wrong answer looks like |
|---|---|---|
| Host | ip route get 10.8.0.20 | Leaves a physical interface instead of tun0 |
| Container | ip route | Only 172.17.0.0/16 via 172.17.0.1 |
| Container DNS | cat /etc/resolv.conf | A public resolver, or an upstream the tunnel never pushed |
| WSL | ip addr; ip route | Only the WSL subnet, no Windows VPN adapter |
यदि कन्टेनरको एकमात्र रुट ब्रिज हो र tun0 उसको नामस्थानमा कहिल्यै देखिँदैन भने, तलको कुनै कुराले मद्दत गर्दैन: कुनै नेमसर्भर परिवर्तनले रुट बनाउँदैन, र कुनै रुटले पियरले स्वीकार गर्ने टनेल पहिचान बनाउँदैन। क्रम महत्त्वपूर्ण छ किनकि शेलको भित्रबाट DNS असफलता र रुट असफलता एउटै देखिन्छ।
रिजोल्भरलाई सार्वजनिकतिर होइन, टनेलतिर निर्देशित गर्नुहोस्
होस्टमा, resolvectl status ले प्रत्येक लिङ्कको DNS सर्भर सूचीबद्ध गर्छ, र readlink -f /etc/resolv.conf ले फाइल systemd स्टब हो, NetworkManager फाइल हो, वा विक्रेताको क्लाइन्टले पुनःलेखेको कुरा हो भनी बताउँछ। प्रयोगकर्ता-परिभाषित नेटवर्कमा रहेको कन्टेनरभित्र, /etc/resolv.conf ले नाम दिन्छ 127.0.0.11, Docker को अन्तर्निहित रिजोल्भरलाई, जसले डेमन कन्फिगर गरिएको upstream मा फर्वार्ड गर्छ। पूर्वनिर्धारित ब्रिजको कन्टेनरले भने सिर्जना हुँदा होस्ट फाइलको प्रतिलिपि पाएको थियो, र त्यसैलाई राख्छ।
त्यही प्रतिलिपिले कन्टेनर सुरु भएपछि माथि आउने टनेलले कन्टेनरलाई पुरानो upstream सोधिरहन दिन्छ। या त VPN रिजोल्भर स्पष्ट रूपमा यससँग पास गर्नुहोस् docker run --dns 10.8.0.53, वा "dns": ["10.8.0.53"] मा /etc/docker/daemon.json सेट गरेर डेमन पुनः सुरु गर्नुहोस्, वा टनेल माथि आएपछि कन्टेनर पुनः सिर्जना गर्नुहोस्। पुनः सिर्जना गर्नु सामान्यतया एक घण्टा अघि सही थियो भन्ने रिजोल्भर डिबग गर्नुभन्दा सस्तो पर्छ।
सार्वजनिक रिजोल्भर राख्नु त्यो मर्मत हो जसले लक्षण कायम राख्छ। यसले इन्टरनेट समाधान गर्छ तर हरेक निजी जोनमा असफल हुन्छ, र टनेल जुन फिल्टरिङका लागि अवस्थित छ त्यसलाई चुपचाप बाइपास गर्न सक्छ। यदि तपाईं चलिरहेको कन्टेनरको /etc/resolv.conf भित्र लेख्न खोज्नुभयो भने, अपेक्षा गर्नुहोस् Device or resource busy: Docker त्यो फाइल bind-mount गर्छ, त्यसैले सम्पादनका लागि पहिले अनमाउन्ट चाहिन्छ। --dns सिर्जना गर्दा सेट गर्नु त्यो क्रम हो जसले पुनः सुरुवातमा टिक्छ।
कन्टेनरहरूले टनेल उधारो लिँदा फर्वार्ड गर्नुहोस् र अनुवाद गर्नुहोस्
पूर्वनिर्धारित ब्रिजसँग, होस्ट docker0 र tun0 बीचको राउटर हो, र पूर्वनिर्धारित रूपमा यसले दुवै काम गर्दैन। फर्वार्डिङ सक्रिय गर्नुहोस् र स्रोत ठेगाना अनुवाद गर्नुहोस् ताकि पियरले फर्किने रुट नभएको ठेगानाको सट्टा होस्टको टनेल ठेगाना देखोस् (tun0 लाई तपाईंको क्लाइन्टले इन्टरफेसलाई दिने नामले बदल्नुहोस्):
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -A FORWARD -i docker0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o docker0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTFORWARD नियमहरू ती होस्टमा महत्त्वपूर्ण छन् जसको फर्वार्ड नीति DROP छ। Docker ले आफ्नै चेनहरू घुसाउँछ, त्यसैले पढ्नुको सट्टा प्याकेटले परीक्षण गर्नुहोस् iptables -S: कन्टेनरबाट, ip route get 10.8.0.20 ले ब्रिज गेटवेको नाम लिनुपर्छ, र nc -vz 10.8.0.20 443 रिजोल्भरमा होइन, टनेलमा जोडिनुपर्छ वा समय सकिनुपर्छ।
MASQUERADE बिना पियरलाई 172.17.0.0/16 मा फर्किने रुट चाहिन्छ, जुन अधिकांश टाढा-पहुँच VPN ले धक्का दिँदैनन्। यहीँ नीति-आधारित क्लाइन्टले योजना तोड्छ: यदि यसले केवल निश्चित UID वा cgroups को ट्राफिक समात्छ भने, तपाईंका फर्वार्ड नियमहरूले टनेलभित्रको प्याकेट कहिल्यै देख्दैनन्, र सुधार iptables मा होइन, क्लाइन्टको राउटिङ नीतिमा पर्छ। हातले थपिएका नियम रिबुटमा हराउँछन्, त्यसैले तिनलाई systemd इकाइ वा netfilter-persistent तालिकामा राख्नुहोस् र रिबुटपछि फेरि परीक्षण गर्नुहोस्, किनकि ढिलो माथि आउने टनेलले तिनलाई बगाउन सक्छ।
लक्ष्य अलगाव भए टनेल कन्टेनरभित्र राख्नुहोस्
यदि एउटा कन्टेनरले निश्चित नोडबाट बाहिर जानुपर्छ भने, त्यही कन्टेनरमा क्लाइन्ट चलाउनुहोस्. यसलाई --cap-add NET_ADMIN र --device /dev/net/tun चाहिन्छ, र त्यसपछि यसको आफ्नै tun0, रुट र फायरवाल हुन्छ। यदि अन्य कन्टेनर यसबाट जान्छन् भने, कन्टेनरभित्र फर्वार्डिङ र MASQUERADE नियम पनि चाहिन्छ, र ती पियरहरूलाई यसतिर देखाउने स्पष्ट रुट वा प्रोक्सी चाहिन्छ; Docker को पूर्वनिर्धारित ब्रिजले त्यो रुट तपाईंको लागि थप्दैन।
होस्ट नेटवर्किङ, docker run --network host, सस्तो संस्करण हो: कन्टेनर होस्टको नामस्थानमा सामेल हुन्छ र टनेलका रुटहरू सीधै देख्छ। यसले नेटवर्क अलगाव पनि छोड्छ, पोर्ट ठोक्किन आमन्त्रण गर्छ, र व्यवहारमा यो Linux विकल्प हो। प्रकाशित पोर्ट यसको विकल्प होइन। -p 8080:80 ले सेवालाई होस्टबाट पहुँचयोग्य बनाउँछ; आन्तरिक 10.x ठेगानाहरूलाई कन्टेनरभित्रबाट पहुँचयोग्य बनाउँदैन, र दुवैलाई मिसाउनु नै राउटिङ समस्या खुला डाटाबेस पोर्ट बन्ने बाटो हो।
नाम असफलतालाई ओभरल्यापिङ सबनेटबाट छुट्याउनुहोस्
Docker को पूर्वनिर्धारित ब्रिज 172.17.0.0/16 हो, र धेरै कर्पोरेट VPN पूल 172.16.0.0/12 भित्र छन्। टनेलले त्यो दायरा ओगटेपछि, कन्टेनरका लागि भएको ट्राफिक त्यसको सट्टा टनेलमा राउट हुन सक्छ। नामहरू असफल हुन्छन्, त्रुटि DNS जस्तो देखिन्छ, र समस्या ठेगानाहरूमा छ। गन्तव्य जाँच्नुहोस्, रिजोल्भर होइन: ip route get 172.17.0.5 होस्टमा, त्यसपछि ब्रिज प्रिफिक्सको VPN पूल र docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' सँग तुलना गर्नुहोस्।
मर्मत भनेको दायराहरूमध्ये एउटा सार्नु हो: या त daemon.json मा Docker का लागि फरक पूर्वनिर्धारित ठेगाना पूल, वा कन्सन्ट्रेटरमा फरक पूल। यहाँ अर्को नेमसर्भर थप्दा केही हुँदैन, र ssh -b ले पनि हुँदैन: क्लाइन्टलाई इन्टरफेसमा बाँध्दा स्रोत ठेगाना बदलिन्छ, टनेलतिर देखाउने गन्तव्य रुट होइन। छिटो काम विभाजन: होस्टमा समाधान हुने तर कन्टेनरमा नहुने नाम रिजोल्भर समस्या हो, जबकि कन्टेनरमा अड्किने तर होस्टमा काम गर्ने सीधा IP जडान रुट वा फर्वार्ड-चेन समस्या हो।
WSL र Docker Desktop ले Linux का नियम पालना गर्दैनन्
आफ्नो पूर्वनिर्धारित NAT मोडमा, WSL आफ्नै भर्चुअल एडाप्टरको पछाडि बस्छ र Windows VPN का आन्तरिक रुट वा DNS सफिक्स पाउँदैन, त्यसैले ब्राउजर चल्छ र ping वितरणभित्र चल्दैन। हालका Windows 11 बिल्डमा उपलब्ध मिरर नेटवर्किङले त्यसको सट्टा होस्ट इन्टरफेसहरू साझा गर्छ, तर यसलाई .wslconfig मा सक्षम गरेर वितरण wsl --shutdown ले पुनः सुरु गर्नुपर्छ। सक्रिय मोड wslinfo --networking-mode ले पुष्टि गर्नुहोस्, सुधार लागू गर्नु अघि, किनकि NAT को उत्तर मिरर मोडका लागि गलत छ र उल्टो पनि।
Docker Desktop ले अर्को तह थप्छ। Windows मा Linux कन्टेनरहरू ऐतिहासिक रूपमा vpnkit भनिने NAT कार्यान्वयनको पछाडि बस्छन्, र तिनको मार्ग मूल Linux होस्टभन्दा फरक हुन्छ। Windows कन्टेनरहरू Hyper-V भर्चुअल स्विचमार्फत जोडिन्छन्, र कर्पोरेट क्लाइन्टले त्यो स्विचबाट आउने ट्राफिक रोक्न सक्छ, त्यसैले एउटै मेसिनका Linux कन्टेनरहरू नेटवर्कमा पुग्न सक्छन् जबकि Windows कन्टेनरसँग केही हुँदैन। भौतिक एडाप्टरमा बाँधिएको बाह्य स्विच सामान्य उपाय हो, र यसले कन्टेनरको नेटवर्क पहिचान नीतिले अनुमति नदिन सक्ने तरिकाले बदल्छ।
अर्को नियम लेख्नु अघि चारै तह क्रममा हिँड्नुहोस् र जहाँ कुनै गलत छ त्यहीँ रोकिनुहोस्:
- कन्टेनरभित्र:
ip routeनिजी प्रिफिक्समा पुग्छ कि, र/etc/resolv.confले त्यसलाई समाधान गर्ने upstream को नाम दिन्छ कि? - होस्टमा: फर्वार्डिङ सक्रिय छ कि, NAT टनेल इन्टरफेसमा बाँधिएको छ कि, र फर्वार्ड चेनले ब्रिजबाट टनेल स्वीकार गर्छ कि?
- पियरमा: यसलाई फर्किने बाटो थाहा छ कि, वा कन्टेनर सबनेट लुकाउन तपाईं NAT मा भर पर्नुहुन्छ?
- प्लेटफर्ममा: WSL NAT वा मिरर मोडमा छ, र कन्टेनर Linux हो वा Windows?
हरेक परीक्षण नयाँ कन्टेनर वा शेलमा फेरि चलाउनुहोस्। क्यास गरिएको उत्तर वा स्थापित जडान भएको लामो प्रक्रिया कन्फिगरेसन सही भएपछि पनि असफल हुँदै जान्छ, र त्यो असफलता काम नगरेको सुधारजस्तै देखिन्छ।