कंटेनरचा पॅकेट कधीही tun0 पर्यंत पोहोचत नाही, आणि कंटेनरवरील अतिरिक्त क्षमता ते बदलणार नाहीत. पाहुणा आणि टनेल यांच्यात दोन राउट शोध आहेत: एक पाहुण्याच्या नेटवर्क नामस्थानात, एक फ्रेम ब्रिजवर उतरल्यानंतर होस्टवर, आणि दुसरा वेगळ्या जुळणी नियमांच्या वेगळ्या तक्त्याला विचारतो. माझी संदर्भ रचना एक Linux होस्ट आहे ज्यावर OpenVPN क्लायंट चालतो, तो 10.8.0.10 हा tun0 वर ठेवतो, 172.18.0.0/16 वर Docker ब्रिज, आणि फक्त टनेलची बाजू पोहोचू शकणारा खाजगी पत्ता. उद्दिष्ट अरुंदच राहते: ते पाहुणे सबनेट टनेलमधून बाहेर जाते, होस्ट त्याचे नेहमीचे अपलिंक ठेवते.

VPN क्लायंट कंटेनरमध्ये चालवणे ही वेगळी रचना आहे, सोपा मार्ग नाही. मग कंटेनर स्वतःचे टनेल आणि ओळखपत्रे बाळगतो, आणि काम iptables मध्ये राहण्याऐवजी Dockerfile मध्ये जाते.

फॉरवर्डिंग गंतव्यानुसार मार्ग निवडते, नंतर NAT स्रोत पुन्हा लिहिते

जेव्हा net.ipv4.ip_forward=1 सेट असतो, तेव्हा फॉरवर्ड केलेला पॅकेट मुख्य तक्त्यात फक्त गंतव्यानुसार राउट होतो. त्या निर्णयात स्रोताचा काही वाटा नसतो. मार्ग निवडल्यावरच कर्नेल POSTROUTING चालवते, आणि तिथेच Docker चा स्वतःचा नियम बसतो: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE. ब्रिज सोडून दुसऱ्या इंटरफेसकडे जाणारे सर्व भाषांतरित होते, आणि ते कोणता पत्ता होते हे मार्गाने ते कोणत्या इंटरफेसकडे पाठवले यावर अवलंबून असते.

हा नियम मला विचारलेल्या बहुतेक लक्षणांचे स्पष्टीकरण देतो. मुख्य तक्त्यात खाजगी गंतव्यासाठी मार्ग नसल्यास, पॅकेट होस्टच्या भौतिक पत्त्यासह अपलिंकमधून बाहेर पडतो. तुमचा प्रदाता गंतव्य टाकून देतो, किंवा दूरची साइट कधीही न अपेक्षित असलेला RFC 1918 स्रोत टाकून देते, आणि टनेल वर आणि निरोगी असतानाच कंटेनरची वेळ संपते. tun0 वर कॅप्चर काहीही दाखवत नाही, आणि हाच संकेत आहे. मार्ग खरोखर tun0 कडे निर्देश करत असेल, तर MASQUERADE स्रोत 10.8.0.10 वर पुन्हा लिहिते, आणि तोच कंटेनर तुम्ही काहीही न स्पर्शता चालतो.

पाहुण्याचा स्रोत नाव देणारा शोध मागा. from आणि iif शिवाय होस्ट स्वतःच्या सॉकेटसाठी उत्तर देतो आणि फॉरवर्ड केलेला पॅकेट कधीही न घेणारा मार्ग सांगतो:

ip route get 192.168.11.222 from 172.18.0.5 iif br-appnet

ते उत्तर अपलिंकचे नाव घेत असेल, तर टनेल चित्रात नाही आणि टनेलच्या बाजूची कोणतीही सेटिंग मदत करणार नाही.

पाहुण्याला टनेलच्या स्वतःच्या पत्त्यावर आणा

सर्वात लहान चालणारा बदल म्हणजे बाहेर पडताना स्पष्ट स्रोत पुनर्लेखन. तो जोडण्याऐवजी घाला: Docker आधीच POSTROUTING च्या टोकाला बसले आहे, म्हणून -A ने जोडलेला नियम Docker च्या नियमानंतर मूल्यमापन होतो आणि कधीही चालत नाही.

iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10

हे टिकेल का हे दोन अटी ठरवतात. पत्ता क्लायंटकडे खरोखर असलेलाच असावा, म्हणून प्रत्येक क्लायंटसाठी ifconfig-push 10.8.0.10 255.255.255.0 असलेल्या नोंदीने तो पिन करा; कधीही न दिलेल्या पत्त्याचे नाव घेणारा नियम त्रुटी नव्हे, तर शांत बाद होणे निर्माण करतो. आणि दूरच्या बाजूने तो स्रोत स्वीकारून उत्तरे परत राउट करायला हवीत, म्हणूनच तिथल्या परवानगी यादीत पाहुणे सबनेट नव्हे, टनेलचा पत्ता असतो. क्लायंटचा पत्ता गतिशील असताना, -j MASQUERADE सह -o tun0 इंटरफेसकडे जे आहे त्याचे अनुसरण करते, पण स्थिर मूल्याविरुद्ध लिहिता न येणाऱ्या दूरच्या धोरणाच्या किमतीवर.

फिल्टरिंग हा दुसरा अर्धा भाग. Docker FORWARD धोरण drop वर ठेवते आणि प्रत्येक डेमॉन रीस्टार्टला स्वतःच्या साखळ्या रिकाम्या करते, म्हणून स्थानिक धोरण DOCKER-USER मध्ये ठेवा, जे टिकते:

iptables -I DOCKER-USER -i br-appnet -o tun0 -j ACCEPT
iptables -I DOCKER-USER -i tun0 -o br-appnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

परतीचा नियम महत्त्वाचा: tun0 वर येणारे उत्तर ब्रिजने उघडलेल्या कनेक्शनसाठी फक्त बाहेरची दिशा स्वीकारली गेली होती म्हणून स्वीकारले जात नाही.

स्रोत नियमाने होस्ट थेट ठेवा

जेव्हा संपूर्ण ब्रिजने टनेल वापरावे पण होस्टवर दुसरे काहीही नाही, तेव्हा NAT वगळा आणि त्या स्रोताला स्वतःचा तक्ता द्या. पाहुणे पत्ते मग सुरुवातीपासून शेवटपर्यंत दिसतात.

echo "200 vpnbox" >> /etc/iproute2/rt_tables
ip rule add from 172.18.0.0/16 lookup vpnbox pref 1000
ip route add default dev tun0 table vpnbox

नियम मुख्य तक्त्यापूर्वी पाहिले जातात, आणि from स्रोताशी जुळतो. टनेलचे स्वतःचे बाह्य पॅकेट होस्टचा भौतिक स्रोत वाहतात, म्हणून ते कधीही from 172.18.0.0/16 शी जुळत नाहीत आणि टनेल स्वतःला परत आत राउट करू शकत नाही. हेच स्वतःला वगळणे रचना स्थिर करते.

परतीच्या मार्गाला आता मदत हवी. दूरची बाजू भाषांतर न केलेला 172.18.0.x पाहते आणि तो कुठे आहे हे जाणून घेण्याचे कारण नसते. सर्व्हरवर प्रत्येक क्लायंटसाठी फाइलला iroute 172.18.0.0 255.255.0.0 हवे, जेणेकरून सर्व्हरचा अंतर्गत तक्ता तो उपसर्ग या क्लायंटला देईल, आणि ढकललेला route 172.18.0.0 255.255.0.0 हवा, जेणेकरून इतर क्लायंटना कळेल की तो आहे.

विश्वास ठेवण्यापूर्वी दोन तपासण्या. चालवा ip route show default : redirect-gateway def1 सह तक्त्यात 0.0.0.0/1 आणि 128.0.0.0/1 आहेत tun0 मधून, आणि होस्ट अजिबात थेट नाही, कारण ते अर्ध-डीफॉल्ट default बदलल्याशिवाय जिंकतात. ip rule add ने जोडलेले नियमही रीबूटवर नाहीसे होतात, म्हणून ते up स्क्रिप्टमध्ये ठेवा.

पॅकेटचा आकार हा दुसरा अपयश आहे जो तुम्हाला भेटेल

1500 बाइटचा ब्रिज इंटरफेस बाह्य UDP आणि IP शीर्षके जोडल्यावर टनेलला त्याच्या क्षमतेपेक्षा जास्त देतो. लहान देवघेव पार होते, म्हणून DNS सुटतो आणि TLS हस्तांदोलन पूर्ण होते, नंतर मोठा अपलोड कुठेही त्रुटीशिवाय अडकतो. प्रेषक तोच सेगमेंट आकार पुन्हा पुन्हा करतो, कारण लहान व्हा असे सांगणारा ICMP तुकडा-आवश्यकता संदेश कधीही पोहोचत नाही.

इंटरफेसवर, MSS वर, किंवा दोन्हीवर ते दुरुस्त करा. क्लॅम्पिंगला पाहुण्याच्या सहकार्याची गरज नाही:

ip link set dev tun0 mtu 1400
iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

क्लॅम्प फक्त TCP पुन्हा लिहिते. UDP, QUIC सह, त्याऐवजी पाहुण्याचा इंटरफेस खाली आणणे आवश्यक आहे, --opt com.docker.network.driver.mtu=1400 ने नेटवर्क तयार करताना किंवा जुळणाऱ्या compose कीसह.

DNS आणि पुन्हा करण्यासारख्या तपासण्या

नाव निराकरण त्याच मार्गाने जाते. Docker चा अंगभूत रिझॉल्व्हर 127.0.0.11 वर होस्टच्या संरचित सर्व्हरकडे पाठवतो, म्हणून कंटेनर होस्ट जे वापरतो ते वारसाहक्काने घेतो. खाजगी झोनला फक्त टनेलमधून पोहोचणारा रिझॉल्व्हर उत्तर देत असेल, तर पाहुण्याला त्या पत्त्याकडे वळवा, आणि getent hosts ने कंटेनरच्या आत तपासा, होस्टवर नाही.

  • अपयशी विनंती पाहुण्याच्या आत चालवा; होस्टच्या बाजूची चाचणी वेगळा स्रोत पत्ता वापरते आणि समस्या लपवते.
  • तुम्ही जोडलेल्या NAT आणि फिल्टर नियमांचे काउंटर वाचा. शून्य जुळणीचा नियम राउटिंगची चूक आहे, धोरणाची नाही.
  • तुमच्या SNAT नियमातील टनेलचा पत्ता क्लायंटकडे खरोखर असलेलाच आहे याची खात्री करा.
  • सर्व्हरला अडकल्याबद्दल दोष देण्यापूर्वी पाहुण्याचा MTU कमी करा किंवा MSS क्लॅम्प करा.

यादी खाली चाला आणि पहिल्या अपयशावर थांबा. तोच थर दुरुस्त करायचा आहे; खाली जे जोडले जाते ते फक्त तुटणारी सीमा लपवते.

संबंधित लेख