Trafik kontena Docker memintas VPN hos: cara menyemaknya
VPN hos hanya meliputi ruang nama rangkaian hos. Gunakan semakan ini untuk mengetahui sama ada trafik kontena di jambatan masuk ke terowong atau keluar terus.
Pelayar anda pada hos menunjukkan alamat keluar VPN, kontena melaporkan sambungan rumah anda, dan seseorang memanggilnya kebocoran. Tiada apa yang bocor. Terowong hos ialah himpunan antara muka, laluan dan peraturan yang tergolong dalam ruang nama rangkaian hos, dan kontena pada jambatan ialah ruang nama lain dengan laluan lalai sendiri. Saya pernah duduk pada timbunan Compose yang klien VPN telah bersambung selama berminggu-minggu dan tidak satu pun paket kontena pernah masuk ke dalamnya.
Semak ruang nama sebelum ikon dulang
Ruang nama ialah keseluruhan hujah. Apabila Docker memulakan kontena pada rangkaian jambatan, ia mencipta ruang nama rangkaian, memasang satu hujung pasangan veth di dalamnya, dan memberikan ruang nama itu alamat serta laluan lalai. Antara muka terowong, apa pun namanya, hidup dalam ruang nama hos. Trafik di dalam kontena tidak dapat melihatnya, dan tiada tetapan klien mengubahnya dari luar.
Dua langkah yang disokong mengeluarkan anda daripada pengasingan. --network host meletakkan kontena di dalam ruang nama hos, jadi ia mewarisi laluan hos dan seterusnya terowong. --network container:vpn berkongsi ruang nama kontena lain, dan begitulah kebanyakan reka bentuk sidecar menghantar beban kerja melalui kontena VPN. Kedua-duanya pilihan eksplisit; biasanya hanya satu daripadanya ialah apa yang dimaksudkan oleh orang yang menggunakan sistem.
Mod hos bukan peningkatan percuma. Kontena berhenti mempunyai alamat sendiri, penerbitan port berhenti terpakai, dan proses yang memegang NET_ADMIN di situ boleh menulis semula penghalaan hos. Menerima perkara itu mungkin keputusan yang betul. Menganggap ia sudah dihidupkan ialah cara orang menghabiskan satu malam menyahpepijat terowong yang tidak pernah berada di laluan.
Ikut paket keluar dari jambatan
Kontena jambatan menghantar paketnya ke get laluan lalainya, iaitu antara muka jambatan pada hos. Hos kemudian memajukan paket itu dan, dalam konfigurasi lalai, menterjemah alamat sumber kepada alamatnya sendiri sebelum paket keluar. Langkah terjemahan itulah yang menewaskan dasar secara senyap.
Apabila paket sampai ke titik akhir terowong, ia membawa alamat hos. Sebarang peraturan, laluan dasar atau keputusan terowong berpecah yang bergantung pada alamat asal kontena berhenti sepadan, dan dua kontena yang sepatutnya keluar melalui laluan berbeza tidak dapat dibezakan hanya melalui sumber. Jika anda memerlukan penghalaan setiap kontena, keputusan mesti dibuat sebelum terjemahan atau di dalam ruang nama yang anda kawal.
Docker menyelenggara peraturan ini sendiri, melalui backend tembok api yang mana daemon dikonfigurasikan. Peraturan yang ditulis dengan tangan di luar cangkuk yang disokong untuk trafik yang dimajukan, DOCKER-USER, boleh disusun semula atau digugurkan apabila daemon dimulakan semula atau hos dinaik taraf. Dokumentasi Docker tentang penapisan paket menunjukkan susunan rantai; perkara praktikalnya ialah setiap peraturan memerlukan pemilik dan laluan muat semula yang benar-benar anda uji.
Uji kedua-dua sistem secara berasingan
Bukti daripada satu ruang nama tidak mengatakan apa-apa tentang yang lain. Permintaan yang dijalankan di dalam kontena VPN membuktikan terowong berfungsi untuk kontena itu. Itu bukan bukti tentang hos, dan arahan yang sama dijalankan dari kontena --network host bukan bukti tentang jambatan.
# host namespace
ip route get 1.1.1.1
ip -brief addr show
# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'
Kemudian ulangi ujian di dalam kontena aplikasi sebenar dan bukan imej yang serupa. Aplikasi mungkin membawa laluan tambahan, pemboleh ubah persekitaran proksi atau penyelesai berbeza, dan setiap satu mengubah jawapannya. Semak penyelesaian nama dan keluarga alamat kedua setiap kali: kontena pada jambatan yang ditakrifkan pengguna diselesaikan melalui penyelesai terbina dalam Docker pada 127.0.0.11, dan laluan lalai IPv6 pada jambatan boleh membawa trafik keluar semasa anda sibuk menguji terowong yang hanya IPv4.
Baca corak sebelum menyentuh kelayakan
Apabila hos berfungsi dan kontena tidak, puncanya hampir selalu struktur, dan memutar kunci atau memasang semula klien membazirkan sebelah petang. Susun simptom dahulu dan pembetulan biasanya menamakan dirinya sendiri.
| What you see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop the tunnel with a request in flight |
Baris pertindihan berhak mendapat ayatnya sendiri. Profil VPN yang menolak laluan untuk 172.17.0.0/16, atau untuk 10.0.0.0/8 yang kebetulan mengandungi awalan jambatan anda, membuatkan terowong menuntut subnet kontena, dan balasan ke alamat yang diterjemah akan menuju arah yang salah atau hilang. Menomborkan semula rangkaian Docker biasanya lebih bersih daripada mengumpul pengecualian.
Jadikan liputan eksplisit, kemudian pecahkannya dengan sengaja
Dua reka bentuk bertahan dalam semakan. Kongsi ruang nama kontena VPN dan setiap beban kerja yang dilindungi menggunakan satu terowong dengan satu sempadan mula semula, yang mudah sehingga satu perkhidmatan memerlukan laluan keluar berbeza atau laluan DNS sendiri. Atau halakan rangkaian kontena ke get laluan VPN pada hos: pemajuan dihidupkan, awalan jambatan dihalakan ke terowong, trafik balik dikendalikan secara eksplisit. Itu membeli kawalan setiap rangkaian dan mengenakan satu set peraturan untuk anda selenggara sepanjang peningkatan daemon dan klien.
Walau apa pun, ujian yang penting ialah kes kegagalan. Hentikan terowong semasa permintaan kontena sedang dalam perjalanan dan lihat ke mana paket pergi. Jika ia jatuh kembali ke laluan terus, liputan tidak pernah dikuatkuasakan, kerana kill switch klien mengawal trafik klien itu sendiri dan bukan paket yang dimajukan dari jambatan. Kemudian mulakan semula daemon dan hos dan sahkan hasilnya kali kedua; itulah saat peraturan yang ditulis dengan tangan hilang.
Sebelum menyebutnya selesai, sahkan empat perkara: antara muka terowong berada dalam ruang nama yang sama dengan trafik, ujian kontena dijalankan di dalam kontena sebenar, penyelesaian nama dan kedua-dua keluarga alamat disemak, dan ujian kegagalan terowong masih gagal tertutup. Kemudian catat backend tembok api, versi klien dan pemilik setiap peraturan. Rekod itulah yang menghalang peningkatan seterusnya daripada meninggalkan campuran andaian lama yang tidak didokumenkan.