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 नभएको होस्ट ठेगानामा केही सुन्दैन। तीमध्ये प्रत्येक उत्पादनमा चुपचाप असफल हुन्छ, र प्रत्येक माथिको एक-लाइन जाँच हो।