హోస్ట్ 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?
ప్రతి పరీక్షను కొత్త కంటైనర్ లేదా షెల్లో మళ్లీ నడపండి. క్యాష్ చేసిన సమాధానం లేదా ఏర్పాటైన కనెక్షన్ ఉన్న దీర్ఘకాలిక ప్రక్రియ కాన్ఫిగరేషన్ సరైన తర్వాత కూడా విఫలమవుతూనే ఉంటుంది, ఆ వైఫల్యం పనిచేయని మరమ్మత్తు లాగానే కనిపిస్తుంది.