होस्ट 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 आहे?
प्रत्येक चाचणी नव्या कंटेनर किंवा शेलमध्ये पुन्हा चालवा. कॅश केलेले उत्तर किंवा प्रस्थापित कनेक्शन असलेली दीर्घकालीन प्रक्रिया कॉन्फिगरेशन बरोबर झाल्यावरही अयशस्वी होत राहील, आणि ती अयशस्वीता न चाललेल्या दुरुस्तीसारखीच दिसते.