Lalu lintas kontainer Docker melewati VPN host: cara memeriksanya
VPN host hanya mencakup ruang nama jaringan host. Gunakan pemeriksaan ini untuk mengetahui apakah lalu lintas kontainer di jembatan masuk ke terowongan atau keluar langsung.
Browser Anda di host menampilkan alamat keluar VPN, kontainer melaporkan koneksi rumah Anda, dan seseorang menyebutnya kebocoran. Tidak ada yang bocor. Terowongan host adalah kumpulan antarmuka, rute, dan aturan yang termasuk dalam ruang nama jaringan host, dan kontainer di jembatan adalah ruang nama lain dengan rute bawaannya sendiri. Saya pernah duduk di tumpukan Compose yang klien VPN-nya sudah terhubung berminggu-minggu dan tidak satu pun paket kontainer pernah masuk ke dalamnya.
Periksa ruang nama sebelum ikon baki
Ruang nama adalah seluruh argumennya. Saat Docker menjalankan kontainer di jaringan jembatan, ia membuat ruang nama jaringan, memasang salah satu ujung pasangan veth di dalamnya, dan memberi ruang nama itu alamat serta rute bawaan. Antarmuka terowongan, apa pun namanya, hidup di ruang nama host. Lalu lintas di dalam kontainer tidak bisa melihatnya, dan tidak ada pengaturan klien yang mengubahnya dari luar.
Dua langkah yang didukung mengeluarkan Anda dari isolasi. --network host menempatkan kontainer di dalam ruang nama host, sehingga ia mewarisi rute host dan karena itu terowongan. --network container:vpn berbagi ruang nama kontainer lain, dan begitulah sebagian besar desain sidecar mengirim beban kerja melalui kontainer VPN. Keduanya adalah pilihan eksplisit; biasanya hanya satu di antaranya yang dimaksud oleh orang yang menerapkan.
Mode host bukan peningkatan gratis. Kontainer berhenti memiliki alamatnya sendiri, publikasi port berhenti berlaku, dan proses yang memegang NET_ADMIN di sana dapat menulis ulang perutean host. Menerima itu bisa jadi keputusan yang tepat. Menganggapnya sudah aktif adalah cara orang menghabiskan satu malam men-debug terowongan yang tidak pernah ada di jalurnya.
Ikuti paket keluar dari jembatan
Kontainer di jembatan mengirim paketnya ke gateway bawaannya, yaitu antarmuka jembatan di host. Host lalu meneruskan paket itu dan, dalam konfigurasi bawaan, menerjemahkan alamat sumber menjadi alamatnya sendiri sebelum paket keluar. Langkah penerjemahan itulah yang diam-diam mengalahkan kebijakan.
Saat paket mencapai titik akhir terowongan, ia membawa alamat host. Aturan, rute kebijakan, atau keputusan terowongan terpisah apa pun yang bertumpu pada alamat asli kontainer berhenti cocok, dan dua kontainer yang dimaksudkan keluar lewat jalur berbeda tidak dapat dibedakan hanya dari sumbernya. Jika Anda memerlukan perutean per kontainer, keputusan harus diambil sebelum penerjemahan atau di dalam ruang nama yang Anda kendalikan.
Docker memelihara aturan ini sendiri, melalui backend firewall apa pun yang digunakan daemon saat dikonfigurasi. Aturan yang ditulis tangan di luar kait yang didukung untuk lalu lintas yang diteruskan, DOCKER-USER, dapat diurutkan ulang atau dihapus saat daemon dimulai ulang atau host ditingkatkan. Dokumentasi Docker tentang penyaringan paket menunjukkan urutan rantai; poin praktisnya adalah setiap aturan memerlukan pemilik dan jalur muat ulang yang benar-benar Anda uji.
Uji kedua sistem secara terpisah
Bukti dari satu ruang nama tidak mengatakan apa pun tentang yang lain. Permintaan yang dijalankan di dalam kontainer VPN membuktikan terowongan bekerja untuk kontainer itu. Itu bukan bukti tentang host, dan perintah yang sama yang dijalankan dari kontainer --network host bukan bukti tentang jembatan.
# 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'
Lalu ulangi pengujian di dalam kontainer aplikasi yang sebenarnya, bukan pada image yang mirip. Aplikasi mungkin membawa rute tambahan, variabel lingkungan proksi, atau resolver berbeda, dan masing-masing mengubah jawabannya. Periksa resolusi nama dan keluarga alamat kedua setiap kali: kontainer pada jembatan yang ditentukan pengguna diselesaikan melalui resolver bawaan Docker di 127.0.0.11, dan rute bawaan IPv6 di jembatan dapat membawa lalu lintas keluar saat Anda sibuk menguji terowongan yang hanya IPv4.
Baca polanya sebelum menyentuh kredensial
Saat host berfungsi dan kontainer tidak, penyebabnya hampir selalu struktural, dan merotasi kunci atau memasang ulang klien membuang satu sore. Urutkan gejalanya lebih dulu dan perbaikannya biasanya menamai 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 tumpang tindih berhak mendapat kalimatnya sendiri. Profil VPN yang mendorong rute untuk 172.17.0.0/16, atau untuk 10.0.0.0/8 yang kebetulan memuat prefiks jembatan Anda, membuat terowongan mengklaim subnet kontainer, dan balasan ke alamat yang diterjemahkan akan menuju arah yang salah atau hilang. Menomori ulang jaringan Docker biasanya lebih bersih daripada menumpuk pengecualian.
Buat cakupan menjadi eksplisit, lalu rusak dengan sengaja
Dua desain bertahan dalam tinjauan. Bagikan ruang nama kontainer VPN dan setiap beban kerja yang tercakup memakai satu terowongan dengan satu batas mulai ulang, yang sederhana sampai satu layanan membutuhkan jalur keluar berbeda atau jalur DNS sendiri. Atau arahkan jaringan kontainer ke gateway VPN di host: penerusan diaktifkan, prefiks jembatan diarahkan ke terowongan, lalu lintas balik ditangani secara eksplisit. Itu membeli kendali per jaringan dan memakan satu set aturan yang harus Anda pelihara selama peningkatan daemon dan klien.
Bagaimanapun, pengujian yang penting adalah kasus kegagalan. Hentikan terowongan saat permintaan kontainer sedang berjalan dan lihat ke mana paket pergi. Jika ia kembali ke jalur langsung, cakupan tidak pernah ditegakkan, karena kill switch klien mengatur lalu lintas klien itu sendiri dan bukan paket yang diteruskan dari jembatan. Mulai ulang daemon dan host setelah itu dan konfirmasi hasilnya untuk kedua kalinya; itulah saat aturan yang ditulis tangan menghilang.
Sebelum menyebutnya selesai, pastikan empat hal: antarmuka terowongan berada di ruang nama yang sama dengan lalu lintas, uji kontainer dijalankan di dalam kontainer sebenarnya, resolusi nama dan kedua keluarga alamat diperiksa, dan uji kegagalan terowongan masih gagal tertutup. Lalu catat backend firewall, versi klien, dan pemilik setiap aturan. Catatan itulah yang mencegah peningkatan berikutnya meninggalkan campuran asumsi lama yang tidak terdokumentasi.