Docker VPN കണ്ടെയ്നർ വഴി ഹോസ്റ്റ് ട്രാഫിക് എങ്ങനെ റൂട്ട് ചെയ്യാം
VPN കണ്ടെയ്നർ ഒരു നെറ്റ്വർക്ക് നെയിംസ്പേസ് ആണ്, പ്രോക്സി അല്ല। പങ്കിട്ട netns, യഥാർത്ഥ SOCKS ശ്രോതാവ് അല്ലെങ്കിൽ റൂട്ട് ചെയ്ത ഗേറ്റ്വേ തിരഞ്ഞെടുത്ത്, ശേഷം എക്സിറ്റ് പാത്ത് പരിശോധിക്കുക।
നിങ്ങളുടെ ടണൽ കണ്ടെയ്നർ പ്രവർത്തിക്കുന്നു, docker compose exec vpn curl -s https://ifconfig.me ദാതാവിന്റെ വിലാസത്തിൽ ഉത്തരം നൽകുന്നു, എന്നിട്ടും നിങ്ങളുടെ ഡെസ്ക്ടോപ്പിലെ ബ്രൗസർ ഇപ്പോഴും നിങ്ങളുടെ ISP വഴി പുറത്തുപോകുന്നു। ആ വിടവ് പ്രതീക്ഷിതമാണ്। VPN ക്ലയന്റ് പ്രവർത്തിപ്പിക്കുന്ന കണ്ടെയ്നർ ഒരു നെറ്റ്വർക്ക് നെയിംസ്പേസ്, റൂട്ടുകൾ, ടണൽ ഇന്റർഫേസ് എന്നിവ കൈവശം വയ്ക്കുന്നു, HTTP അല്ലെങ്കിൽ SOCKS സംസാരിക്കുന്ന ഒന്നും വയ്ക്കുന്നില്ല; അതിൽ പോർട്ട് പ്രസിദ്ധീകരിച്ചാൽ ഒരിക്കലും ഉണ്ടായിരുന്നില്ലാത്ത ഒരു ശ്രോതാവിനെ സൃഷ്ടിക്കാനാകില്ല।
ക്ലയന്റ് എവിടെ പ്രവർത്തിക്കുന്നു എന്നത് രൂപകൽപ്പന തീരുമാനിക്കുന്നു। സഹോദര കണ്ടെയ്നറിന് ടണലിന്റെ നെയിംസ്പേസിലേക്ക് മാറാം, ഡെസ്ക്ടോപ്പ് ആപ്ലിക്കേഷന് കഴിയില്ല, റൗട്ടറിന് പ്രോക്സി ഫീൽഡല്ല, റൂട്ടുകളാണ് വേണ്ടത്। മാപ്പിംഗ് തെറ്റായാൽ ലക്ഷണം അതേതുതന്നെ: കണക്ഷൻ നിരസിച്ചു, അല്ലെങ്കിൽ നിശ്ശബ്ദമായി പഴയ പാതയിലൂടെ പോകുന്ന ട്രാഫിക്।
ക്ലയന്റ് പ്രവർത്തിക്കുന്ന സ്ഥലത്തിന് അനുസരിച്ച് ക്രമീകരണം മാറ്റുക
Compose എഡിറ്റ് ചെയ്യുന്നതിന് മുമ്പ് ഒരു ചോദ്യം ചോദിക്കുക: VPN കണ്ടെയ്നറിന്റെ നെറ്റ്വർക്ക് നെയിംസ്പേസിനുള്ളിൽ ക്ലയന്റ് ആരംഭിക്കാനാകുമോ? ഇതിനകം Linux കണ്ടെയ്നറായി പ്രവർത്തിക്കുന്ന എന്തും കഴിയും। നിങ്ങളുടെ മേശയിലെ ബ്രൗസർ, IDE അല്ലെങ്കിൽ CLI കഴിയില്ല, കാരണം അതിന്റെ പ്രോക്സി ക്രമീകരണം ഒരു പ്രോട്ടോക്കോൾ സേവനത്തെ പ്രതീക്ഷിക്കുന്നു, നെയിംസ്പേസിനെയല്ല।
| Client | Arrangement | What must already exist |
|---|---|---|
| Another Compose service | Shares the vpn namespace via network_mode: service:vpn | A working tunnel and correct start order |
| Host browser, IDE or CLI | Proxy listener inside the namespace, published to host loopback | A configured SOCKS or HTTP proxy and its access rules |
| Router, VM or phone | The container as a layer-3 gateway | Forwarding, NAT and a return route |
ഈ മൂന്നും കൂടിച്ചേരില്ല। കണ്ടെയ്നറിന്റെ ബ്രിഡ്ജ് വിലാസത്തിലേക്ക് ചൂണ്ടുന്ന HTTP പ്രോക്സി ഫീൽഡ് അവിടെ പ്രോക്സി കേൾക്കുന്നില്ലെങ്കിൽ ഒന്നിനെയും എത്തുന്നില്ല, പ്രോക്സി ശ്രോതാവ് റൗട്ടറിന്റെ ട്രാഫിക് റൂട്ട് ചെയ്യുന്നുമില്ല। ആദ്യം തീരുമാനിക്കുക, പിന്നീട് ബന്ധപ്പെട്ട വിഭാഗം പിന്തുടരുക।
ടണൽ നെയിംസ്പേസ് സഹോദര കണ്ടെയ്നറുമായി പങ്കിടുക
പ്രോക്സി പ്രോട്ടോക്കോൾ ഉൾപ്പെടാത്തതിനാൽ ഇതാണ് ഏറ്റവും വിലകുറഞ്ഞ ഓപ്ഷൻ। ആപ്ലിക്കേഷൻ vpn സേവനത്തിന്റെ നെയിംസ്പേസിൽ ചേരുന്നു, അതിന്റെ ഇന്റർഫേസുകൾ, റൂട്ടുകൾ, പോർട്ട് സ്പേസ് എന്നിവ പാരമ്പര്യമായി നേടുന്നു:
services:
vpn:
image: your-vpn-client
cap_add:
- NET_ADMIN
healthcheck:
test: ["CMD-SHELL", "ip link show tun0 >/dev/null"]
interval: 10s
retries: 5
app:
image: your-app
network_mode: service:vpn
depends_on:
vpn:
condition: service_healthyനെയിംസ്പേസ് മറ്റൊരു സേവനത്തിന് ഉള്ളതിനാൽ മൂന്ന് നിയന്ത്രണങ്ങൾ ഉണ്ടാകുന്നു। ആപ്ലിക്കേഷന് സ്വന്തമായി networks കീ ലഭിക്കുന്നില്ല, കാരണം ചേരാൻ നെയിംസ്പേസില്ല। പോർട്ട് പ്രസിദ്ധീകരണം vpn-ൽ ആണ്, കാരണം നെയിംസ്പേസ് അവിടെയാണ് ജീവിക്കുന്നത്। vpn വീണ്ടും സൃഷ്ടിച്ചാൽ ആപ്ലിക്കേഷൻ ചേർന്ന നെയിംസ്പേസ് നശിക്കുന്നു, അതിനാൽ docker compose up -d --force-recreate vpn app-ഉം വീണ്ടും സൃഷ്ടിക്കാൻ നിങ്ങളെ അനുവദിക്കുന്നു; സാധാരണ റീസ്റ്റാർട്ട് എപ്പോഴും മതിയാകില്ല। Compose സേവന റെഫറൻസ് ഈ ക്രമീകരണവും അതിന്റെ പോർട്ട് പ്രസിദ്ധീകരണ നിയന്ത്രണവും ഉൾക്കൊള്ളുന്നു।
റിസോൾവർ കൂടെ വരുമെന്ന് കരുതരുത്। /etc/resolv.conf ഓരോ കണ്ടെയ്നറിനുമുള്ള ഫയലാണ്, നെറ്റ്വർക്ക് നെയിംസ്പേസിന്റെ ഭാഗമല്ല, അതിനാൽ ആപ്ലിക്കേഷന്റെ പാക്കറ്റുകൾ ടണലിലൂടെ പുറത്തുപോകുമ്പോഴും അതിന് ഹോസ്റ്റിന്റെ റിസോൾവറിനോട് ചോദിക്കാം। അത് കണ്ടെയ്നറിനുള്ളിൽ നിന്ന് വായിക്കുക, സ്വകാര്യ നാമങ്ങൾ ടണലിലൂടെ പരിഹരിക്കേണ്ടിവരുമ്പോൾ ആപ്ലിക്കേഷനിൽ dns: സജ്ജീകരിക്കുക।
docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.meറൂട്ട് പട്ടികയിൽ ടണൽ ഇന്റർഫേസ് ഉണ്ടെങ്കിൽ, വിലാസം ദാതാവിന്റേതാണെങ്കിൽ, ആപ്ലിക്കേഷൻ ടണലിനുള്ളിലാണ്। ഇന്റർഫേസ് ഇല്ലെങ്കിൽ, vpn-ന് ടണൽ ഉണ്ടാകുന്നതിന് മുമ്പ് app ആരംഭിച്ചു, അതിനാൽ vpn ആരോഗ്യകരമെന്ന് റിപ്പോർട്ട് ചെയ്താൽ app വീണ്ടും സൃഷ്ടിക്കുക।
ഹോസ്റ്റ് ക്ലയന്റുകൾക്കായി നെയിംസ്പേസിൽ യഥാർത്ഥ പ്രോക്സി ശ്രോതാവ് വയ്ക്കുക
ഡെസ്ക്ടോപ്പ് ബ്രൗസറിന് നെയിംസ്പേസിൽ ചേരാനാകില്ല, അതിനാൽ ടണൽ ഒരു സേവനമായി വെളിപ്പെടുത്തണം। vpn നെയിംസ്പേസിനുള്ളിൽ യഥാർത്ഥ SOCKS അല്ലെങ്കിൽ HTTP പ്രോക്സി പ്രവർത്തിപ്പിച്ച് അതിന്റെ പോർട്ട് മാത്രം പ്രസിദ്ധീകരിക്കുക:
services:
vpn:
ports:
- "127.0.0.1:1080:1080"
proxy:
image: your-proxy
network_mode: service:vpn
command: ["--socks", "0.0.0.0:1080"]ഹോസ്റ്റ് വശത്തെ വിലാസമാണ് ആ മാപ്പിംഗിന്റെ പ്രധാന പകുതി। ഇടതുവശത്തെ 127.0.0.1:1080 ശ്രോതാവിനെ നിങ്ങളുടെ LAN-ന് പുറത്ത് നിർത്തുന്നു; വെറും "1080:1080" നിങ്ങളുടെ മെഷീനിൽ എത്താൻ കഴിയുന്ന ഓരോ ഉപകരണത്തിനും തുറന്ന പ്രോക്സി പ്രസിദ്ധീകരിക്കുന്നു।
കണ്ടെയ്നർ വശത്തിന് സ്വന്തം കെണിയുണ്ട്। പ്രസിദ്ധീകരിച്ച പോർട്ടുകൾ കണ്ടെയ്നറിന്റെ ബ്രിഡ്ജ് വിലാസത്തിൽ എത്തിക്കുന്നു, അതിന്റെ loopback-ലേക്കല്ല, അതിനാൽ നെയിംസ്പേസിനുള്ളിൽ --socks 127.0.0.1:1080 ഉപയോഗിച്ച് ആരംഭിച്ച പ്രോക്സി സഹോദരങ്ങളുടെ കണക്ഷനുകൾ സ്വീകരിക്കുകയും പ്രസിദ്ധീകരിച്ച പോർട്ടിലൂടെ വരുന്ന എല്ലാം നിരസിക്കുകയും ചെയ്യുന്നു। അത് 0.0.0.0-ലേക്ക് ബന്ധിപ്പിച്ച് വേർതിരിവിനായി ഹോസ്റ്റ് വശത്തെ loopback ബോണ്ടിൽ ആശ്രയിക്കുക। അതേ നിയമം പ്രോക്സി കോൺഫിഗ് ഫയലിലെ ലിസൺ വിലാസത്തിനും ബാധകമാണ്।
പിന്നീട് നാമങ്ങൾ എവിടെ പരിഹരിക്കുന്നു എന്ന് തീരുമാനിക്കുക। curl-ൽ --socks5 ഹോസ്റ്റ്നെയിം പ്രാദേശികമായി പരിഹരിക്കുന്നു, --socks5-hostname പേര് പ്രോക്സിയിലേക്ക് അയയ്ക്കുന്നു; ബ്രൗസറുകൾ അതേ സ്വിച്ച് മറ്റൊരു ലേബലിൽ കാണിക്കുന്നു। പ്രാദേശിക പരിഹാരം പേജ് ടണലിലൂടെ ലോഡ് ചെയ്യുമ്പോഴും ക്വറി ചോർത്തുന്നു।
തിരികെ വരുന്ന റൂട്ട് ഉണ്ടെങ്കിൽ മാത്രം കണ്ടെയ്നറിനെ ഗേറ്റ്വേയായി കാണുക
റൗട്ടറുകൾ, VM-കൾ, ഫോണുകൾ എന്നിവ HTTP പ്രോക്സി ഫീൽഡ് ഉപയോഗിക്കില്ല, ചില ആപ്ലിക്കേഷനുകൾ പ്രോക്സി വേരിയബിളുകൾ പൂർണ്ണമായും അവഗണിക്കുന്നു। അവയുടെ ട്രാഫിക് റൂട്ട് ചെയ്യുക എന്നാൽ ലേയർ 3: കണ്ടെയ്നർ പാക്കറ്റുകൾ കൈമാറുന്നു, ടണൽ ഇന്റർഫേസിൽ വിലാസങ്ങൾ വിവർത്തനം ചെയ്യുന്നു।
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEരണ്ടു കാര്യങ്ങൾ എളുപ്പം വിട്ടുപോകുന്നു। ക്ലയന്റിന് അതിന്റെ ഡിഫോൾട്ട് ഗേറ്റ്വേ ഈ ഹോസ്റ്റിലേക്ക് ചൂണ്ടുന്ന ഒരു റൂട്ട് വേണം, മറുപടികൾ തിരികെ വരുന്ന വഴി കണ്ടെത്തണം, ഒന്നുകിൽ മുകളിലെ റൗട്ടറിലെ സ്റ്റാറ്റിക് റൂട്ടിലൂടെ അല്ലെങ്കിൽ ക്ലയന്റുകളിലേക്കുള്ള ഇന്റർഫേസിലെ NAT വഴി। അവയിലൊന്നും ഇല്ലെങ്കിൽ ടണൽ അഭ്യർത്ഥന പുറത്തുകൊണ്ടുപോകുന്നു, മറുപടി അപ്രത്യക്ഷമാകുന്നു।
അതിന്റെ സ്വാധീന പരിധിയും ഏറ്റവും വലുതാണ്। മുഴുവൻ LAN-നും ഗേറ്റ്വേയായി പ്രവർത്തിക്കുന്ന ഹോസ്റ്റ് തെറ്റായി കോൺഫിഗർ ചെയ്ത ഓരോ ക്ലയന്റിനെയും നിങ്ങളുടെ VPN അക്കൗണ്ടിലൂടെ അയയ്ക്കുന്നു, ടണൽ വീണാൽ kill switch അനുസരിച്ച് ഒന്നുകിൽ LAN ഇരുളടയാകും അല്ലെങ്കിൽ ISP-യിലേക്ക് തിരികെപ്പോകും।
എക്സിറ്റ് പാത്ത് പരിശോധിച്ച്, പിന്നീട് ക്രമത്തിൽ തിരികെ മടക്കുക
ഈ ക്രമത്തിൽ പരിശോധിച്ച് ആദ്യ പരാജയത്തിൽ നിർത്തുക: നെയിംസ്പേസിനുള്ളിലെ എക്സിറ്റ് വിലാസം, ഹോസ്റ്റിൽ നിന്ന് പ്രോക്സിയിലൂടെയുള്ള എക്സിറ്റ് വിലാസം, പിന്നീട് സ്വകാര്യ ഹോസ്റ്റിനുള്ള നാമ പരിഹാരം।
docker compose exec vpn curl -s https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 http://internal.example/healthആദ്യ രണ്ട് വിലാസങ്ങൾ ദാതാവുമായി പൊരുത്തപ്പെടണം, മൂന്നാമത്തേത് നാമ പിശകോടെ പരാജയപ്പെടുന്നതിന് പകരം പ്രോക്സിയിലൂടെ പരിഹരിക്കണം। ആദ്യ വരി പൊരുത്തപ്പെടുകയും രണ്ടാമത്തേത് പരാജയപ്പെടുകയും ചെയ്താൽ ശ്രോതാവോ പ്രസിദ്ധീകരിച്ച പോർട്ടോ തെറ്റാണ്, ടണലല്ല।
തിരികെ മടക്കുന്നത് സെറ്റപ്പിന്റെ വിപരീതമാണ്। ഷെൽ പ്രൊഫൈലിൽ നിന്നും ഏതെങ്കിലും systemd യൂണിറ്റിൽ നിന്നും പ്രോക്സി എൺവയൺമെന്റ് വേരിയബിളുകൾ നീക്കം ചെയ്ത്, സ്റ്റാക്ക് താഴ്ത്തുക, അങ്ങനെ പങ്കിട്ട നെയിംസ്പേസ് അതിന്റെ ഉടമയോടൊപ്പം അപ്രത്യക്ഷമാകും। പ്രോക്സി സേവനം ഇല്ലാതാക്കുന്നതിന് മുമ്പ് പ്രസിദ്ധീകരിച്ച പോർട്ട് ഇല്ലാതാക്കുക, അല്ലെങ്കിൽ ഹോസ്റ്റിൽ ആരും വായിക്കാത്ത loopback ശ്രോതാവ് അവശേഷിക്കും।
മുമ്പോട്ട് പോകുന്നതിന് മുമ്പ് നാല് കാര്യങ്ങൾ ഉറപ്പാക്കുക: നിങ്ങൾക്ക് പ്രധാനമായ ക്ലയന്റ് യഥാർത്ഥത്തിൽ ടണലിൽ എത്തുന്നു, നെയിംസ്പേസിന്റെ ഉടമ മാത്രമാണ് പോർട്ടുകൾ പ്രസിദ്ധീകരിക്കുന്നത്, സ്വകാര്യ നാമങ്ങൾ നിങ്ങൾ ഉദ്ദേശിച്ചിടത്ത് പരിഹരിക്കുന്നു, loopback അല്ലാത്ത ഹോസ്റ്റ് വിലാസത്തിൽ ഒന്നും കേൾക്കുന്നില്ല। അവയോരോന്നും ഉത്പാദനത്തിൽ നിശ്ശബ്ദമായി പരാജയപ്പെടുന്നു, ഓരോന്നും മുകളിലെ ഒരു വരി പരിശോധനയാണ്।