Cara menghalakan hanya trafik kontena Docker melalui OpenVPN
Biarkan hos pada uplink biasanya dan letakkan satu subnet kontena dalam terowong: susunan NAT, peraturan sumber, iroute OpenVPN dan pemeriksaan MSS.
Paket kontena tidak pernah sampai ke tun0 dan keupayaan tambahan pada kontena tidak akan mengubahnya. Antara tetamu dan terowong ada dua carian laluan: satu di dalam ruang nama rangkaian tetamu, satu pada hos selepas bingkai mendarat di jambatan, dan yang kedua bertanya jadual lain dengan peraturan padanan berbeza. Susun atur rujukan saya ialah hos Linux yang menjalankan OpenVPN klien yang memegang 10.8.0.10 pada tun0, jambatan Docker pada 172.18.0.0/16, dan alamat persendirian yang hanya boleh dicapai oleh sebelah terowong. Matlamat kekal sempit: subnet tetamu itu keluar melalui terowong sementara hos mengekalkan uplink biasanya.
Menjalankan klien VPN di dalam kontena ialah reka bentuk lain, bukan jalan pintas. Kontena kemudian memiliki terowong dan kelayakannya sendiri, dan kerja berpindah ke Dockerfile dan bukan kekal dalam iptables.
Penghalaan hadapan memilih laluan mengikut destinasi, kemudian NAT menulis semula sumber
Apabila net.ipv4.ip_forward=1 ditetapkan, paket yang dihalakan hadapan dihalakan mengikut destinasi sahaja, dalam jadual utama. Sumber tidak memainkan peranan dalam keputusan itu. Hanya selepas laluan dipilih, kernel menjalankan POSTROUTING , dan di situlah terletaknya peraturan Docker sendiri: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE . Semua yang meninggalkan jambatan ke antara muka lain diterjemah, dan alamat yang menjadi tujuannya bergantung pada antara muka tempat laluan menghantarnya.
Peraturan itu menjelaskan kebanyakan gejala yang ditanyakan kepada saya. Jika jadual utama tiada laluan untuk destinasi persendirian, paket keluar melalui uplink membawa alamat fizikal hos. Penyedia anda membuang destinasi itu, atau tapak jauh membuang sumber RFC 1918 yang tidak pernah dijangka, dan kontena kehabisan masa sementara terowong kekal naik dan sihat. Tangkapan pada tun0 tidak menunjukkan apa-apa, dan itulah tandanya. Jika laluan itu memang menunjuk ke tun0 , MASQUERADE menulis semula sumber ke 10.8.0.10 , dan kontena yang sama berfungsi tanpa anda menyentuh apa-apa.
Minta carian yang menamakan sumber tetamu. Tanpa from dan iif hos menjawab untuk soketnya sendiri dan melaporkan laluan yang tidak akan diambil oleh paket yang dihalakan hadapan:
ip route get 192.168.11.222 from 172.18.0.5 iif br-appnetJika jawapan itu menamakan uplink, terowong tiada dalam gambaran dan tiada tetapan di sebelah terowong akan membantu.
Pindahkan tetamu ke alamat terowong itu sendiri
Perubahan terkecil yang berfungsi ialah penulisan semula sumber yang jelas semasa keluar. Sisipkannya dan jangan tambah di hujung: Docker sudah duduk di kepala POSTROUTING , jadi peraturan yang ditambah dengan -A dinilai di belakang peraturan Docker dan tidak pernah tercetus.
iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10Dua syarat menentukan sama ada ini bertahan. Alamat itu mesti yang benar-benar dipegang oleh klien, jadi pin dengan entri bagi setiap klien yang mengandungi ifconfig-push 10.8.0.10 255.255.255.0 ; peraturan yang menamakan alamat yang tidak pernah diberikan menghasilkan penurunan senyap, bukan ralat. Dan sebelah jauh mesti menerima sumber itu dan menghalakan balasan kembali, sebab itulah senarai kebenaran di sana menamakan alamat terowong dan bukan subnet tetamu. Apabila alamat klien dinamik, -j MASQUERADE dengan -o tun0 mengikut apa yang dipegang oleh antara muka, dengan kos dasar jauh yang tidak boleh anda tulis terhadap nilai tetap.
Penapisan ialah separuh yang lain. Docker menetapkan dasar FORWARD kepada drop dan mengosongkan rantaian miliknya pada setiap permulaan semula daemon, jadi letakkan dasar tempatan dalam DOCKER-USER , yang bertahan:
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 ACCEPTPeraturan balasan penting: balasan yang tiba di tun0 untuk sambungan yang dibuka oleh jambatan tidak diterima hanya kerana arah keluar telah diterima.
Kekalkan hos terus dengan peraturan sumber
Apabila seluruh jambatan harus menggunakan terowong tetapi tiada apa-apa lagi pada hos, langkau NAT dan beri sumber itu jadualnya sendiri. Alamat tetamu kemudian kekal kelihatan dari hujung ke hujung.
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 vpnboxPeraturan dirujuk sebelum jadual utama, dan from sepadan dengan sumber. Paket luar terowong itu sendiri membawa sumber fizikal hos, jadi ia tidak pernah sepadan dengan from 172.18.0.0/16 , dan terowong tidak boleh menghalakan dirinya kembali ke dalam dirinya. Pengecualian diri inilah yang menjadikan susun atur stabil.
Laluan balik kini memerlukan bantuan. Sebelah jauh melihat 172.18.0.x yang tidak diterjemah dan tiada sebab untuk tahu di mana ia tinggal. Pada pelayan, fail bagi setiap klien memerlukan iroute 172.18.0.0 255.255.0.0 supaya jadual dalaman pelayan menyerahkan awalan itu kepada klien ini, dan route 172.18.0.0 255.255.0.0 yang ditolak supaya klien lain tahu ia wujud.
Dua semakan sebelum mempercayainya. Jalankan ip route show default : dengan redirect-gateway def1 jadual memegang 0.0.0.0/1 dan 128.0.0.0/1 melalui tun0 , dan hos sama sekali tidak terus, kerana separuh lalai itu menang tanpa menggantikan default . Peraturan yang ditambah dengan ip rule add juga hilang semasa but semula, jadi bawa dalam skrip up.
Saiz paket ialah kegagalan kedua yang anda temui
Antara muka jambatan pada 1500 bait memberikan terowong lebih daripada yang dapat dibawanya apabila pengepala UDP dan IP luar ditambah. Pertukaran kecil lulus, jadi DNS diselesaikan dan jabat tangan TLS selesai, kemudian muat naik yang lebih besar tergantung tanpa ralat di mana-mana. Penghantar terus mengulang saiz segmen yang sama kerana mesej ICMP tentang keperluan pemecahan, yang akan menyuruhnya mengecil, tidak pernah tiba.
Betulkan pada antara muka, pada MSS, atau kedua-duanya. Pengapitan tidak memerlukan kerjasama tetamu:
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-pmtuPengapitan hanya menulis semula TCP. UDP, termasuk QUIC, sebaliknya memerlukan antara muka tetamu yang lebih rendah, dengan --opt com.docker.network.driver.mtu=1400 semasa mencipta rangkaian atau kunci compose yang sepadan.
DNS dan semakan yang wajar diulang
Penyelesaian nama mengikut laluan yang sama. Penyelesai terbina Docker pada 127.0.0.11 memajukan ke pelayan hos yang dikonfigurasikan, jadi kontena mewarisi apa yang digunakan oleh hos. Apabila zon persendirian hanya dijawab oleh penyelesai yang boleh dicapai melalui terowong, halakan tetamu ke alamat itu, dan uji dengan getent hosts di dalam kontena dan bukan pada hos.
- Jalankan permintaan yang gagal di dalam tetamu; ujian di sebelah hos menggunakan alamat sumber lain dan menyembunyikan masalah.
- Baca pembilang pada peraturan NAT dan penapis yang anda tambah. Peraturan tanpa sebarang padanan ialah kesilapan penghalaan, bukan kesilapan dasar.
- Sahkan alamat terowong dalam peraturan SNAT anda ialah yang benar-benar dipegang oleh klien.
- Turunkan MTU tetamu atau apit MSS sebelum menyalahkan pelayan atas tersekat.
Telusuri senarai itu dan berhenti pada kegagalan pertama. Lapisan itulah yang perlu diperbaiki; apa-apa yang ditambah lebih jauh hanya menyembunyikan sempadan yang pecah.