Bayangkan sebuah host Linux yang mengakhiri VPN dan sekaligus menjalankan kontainer di jaringan macvlan. LAN-nya adalah 192.168.60.0/24, kontainer memegang 192.168.60.210, dan klien VPN datang dari 10.95.0.0/24. Klien mencapai layanan, balasan tidak pernah kembali, dan setiap aturan firewall di host tampak benar. Dua kendala terpisah menghasilkan gejala itu, dan memperbaiki salah satunya membiarkan yang lain tetap di tempatnya.

Dua kendala, satu gejala

Kendala pertama adalah isolasi: driver macvlan Docker tidak mengizinkan kontainer berbicara dengan hostnya sendiri melalui antarmuka induk. Lalu lintas antara tumpukan host dan kontainer tidak punya jalur, betapa pun rute di host ditulis.

Kendala kedua adalah jalur kembali. Gateway default kontainer biasanya router LAN, sehingga balasan yang dialamatkan ke klien VPN keluar melalui router itu. Jika router tidak punya rute kembali ke kumpulan VPN, balasan itu dibuang di suatu tempat di tengah.

Kedua kegagalan itu terlihat identik dari sisi klien: permintaan yang tiba dan jawaban yang tidak pernah datang. Keduanya butuh perbaikan berbeda, dan aturan masquerade yang lebar dapat menyembunyikan mana yang masih rusak. Karena itu uji pertama adalah tangkapan paket di sisi kontainer, bukan perubahan firewall lagi. Jika permintaan tidak pernah muncul di sana, kendala isolasilah yang sedang berlaku.

Bangun shim sisi host secara sempit

Antarmuka macvlan kedua di host, terpasang ke induk yang sama dalam mode jembatan, memberi tumpukan host identitasnya sendiri di segmen LAN itu. Sisihkan alamat di luar kumpulan DHCP dan di luar rentang kontainer untuknya, lalu rutekan hanya kontainer melewatinya.

ip link add macvlan-vpn link eth0 type macvlan mode bridge
ip address add 192.168.60.250/32 dev macvlan-vpn
ip link set macvlan-vpn up
ip route add 192.168.60.210/32 dev macvlan-vpn src 192.168.60.250

Perintah pertama membuat antarmuka dalam mode jembatan, yang merupakan bawaan terdokumentasi untuk driver ini dan mode yang Anda inginkan untuk lalu lintas host-kontainer. Yang kedua menetapkan /32 agar alamat tidak bertabrakan dengan prefiks LAN, dan yang keempat mengirim hanya alamat kontainer melalui shim.

Jangan mengalihkan seluruh LAN melalui antarmuka baru. Rute terhubung biasa tetap seperti adanya, dan rute host sengaja sempit agar satu kontainer mendapat jalur tanpa mengubah perilaku bagian lain segmen. Rute default yang menunjuk ke shim akan menjadi rancangan lain dengan akibat lain. Jaga tetap spesifik dan radius kerusakannya tetap kecil.

Perintah-perintah ini mengubah pengaturan jaringan pada host yang sedang berjalan. Pada perangkat atau platform terkelola, gunakan mekanisme konfigurasi yang didukung platform tersebut, karena perubahan interaktif di root shell mungkin tidak bertahan setelah peningkatan.

Putuskan bagaimana sumber dipertahankan

Dengan shim di tempatnya, kontainer dapat mencapai host, dan pertanyaannya menjadi alamat sumber apa yang dibawa balasan. Mempertahankan sumber VPN asli adalah model yang lebih bersih: kontainer melihat alamat klien yang sebenarnya, dan log serta aturan akses layanan dapat memakainya.

Agar itu berhasil, konfigurasi jaringan kontainer harus mengirim lalu lintas untuk 10.95.0.0/24 ke 192.168.60.250 sebagai gateway untuk jalur ini. Itu pengaturan rute atau gateway yang didukung di dalam konfigurasi kontainer itu sendiri, bukan trik di sisi host. Konfirmasikan dari dalam kontainer daripada menganggap pengaturan itu sudah berlaku. Gateway default yang masih menunjuk ke router LAN akan terus mengirim balasan ke lubang yang sama.

Jika rancangan yang disetujui justru menyembunyikan sumber VPN, batasi terjemahannya secara sempit: kumpulan VPN yang sebenarnya, shim sebagai antarmuka keluar, serta kontainer dan layanan yang spesifik.

iptables -t nat -A POSTROUTING -s 10.95.0.0/24 -o macvlan-vpn -j SNAT --to-source 192.168.60.250

Cocokkan shim sebagai antarmuka keluar, bukan terowongan. Aturan yang menyebut terowongan sebagai antarmuka keluar tidak akan cocok dengan paket yang menuju kontainer, dan itulah kesalahan yang biasanya ada pada penyiapan semacam ini. Jaga aturannya sesempit kalimat di atas dan tinjau kembali ketika kumpulan berubah.

Verifikasi dari klien, bukan dari host

Permintaan dari host itu sendiri, yang terikat ke alamat shim, membuktikan bahwa shim dapat mencapai kontainer. Itu tidak membuktikan bahwa kontainer dapat mengembalikan lalu lintas ke sumber 10.95.0.x yang dipertahankan, karena alamat sumber dalam uji itu adalah milik shim sendiri.

curl -sS --interface 192.168.60.250 -o /dev/null -w '%{http_code}\n' http://192.168.60.210:8080/health
sudo tcpdump -ni macvlan-vpn host 192.168.60.210

Perintah pertama menguji ruas host ke kontainer, dan yang kedua menunjukkan apa yang benar-benar melintasi shim saat klien VPN sungguhan mengirim permintaan. Perhatikan alamat sumber di jalur masuk dan apakah balasan muncul dengan aliran yang sama.

Penerusan harus diaktifkan di host, dan jalur penerusan memerlukan izin untuk kumpulan VPN ke shim pada port layanan ditambah balasan yang sudah terbentuk. Aturan INPUT di host tidak mengizinkan lalu lintas yang diteruskan, dan itu penyebab umum paket dibuang setelah perutean tampak benar.

Jalankan aplikasi sungguhan dengan kredensial sungguhan, lalu periksa bahwa layanan kedua yang tidak terkait di kontainer yang sama masih menolak Anda. Jika satu-satunya cara agar berhasil adalah membuka setiap aturan penerusan, rancangannya belum selesai. Catat juga alamat sumber mana yang dicatat layanan, karena itulah yang akan dipakai aturan aksesnya sendiri mulai sekarang.

Artikel terkait