Layanan Anda berjalan di mesin, tunnel sudah naik, tetapi peramban di meja Anda masih menunggu jawaban. Tidak ada yang rusak dalam arti biasa: aplikasi mendengarkan di dalam namespace jaringan, dan tumpukan itu tidak terlihat oleh LAN. Loopback-nya milik namespace, jadi klien di mesin lain tidak punya alamat yang mencapai port itu. Satu lompatan yang disengaja, atau satu pasangan veth, memperbaikinya tanpa memindahkan sisa host.

Mengapa tidak ada yang menjawab di alamat LAN

Namespace adalah tumpukan jaringan lengkap: antarmuka, rute, aturan firewall, dan loopback pribadi. Proses yang dijalankan melalui ip netns exec hanya melihat tumpukan itu dan tidak yang lain, sehingga alamat yang diikatnya hanya terurai di dalam namespace. 127.0.0.1 milik host sendiri adalah loopback yang sama sekali berbeda.

Itulah sebabnya curl di host gagal sementara perintah yang sama di dalam namespace berhasil. Aplikasinya sehat; alamat itu memang tidak ada di tumpukan host.

Publikasikan satu port dengan lompatan socat

socat menjembatani kedua tumpukan di ruang pengguna, yang cukup saat satu port TCP harus menyeberang. Sisi host mendengarkan di LAN dan, untuk setiap koneksi yang diterima, menjalankan socat kedua di dalam namespace yang tersambung ke loopback aplikasi. Proses dalam mencapai aplikasi persis seperti klien lokal. Tidak ada yang berubah pada perutean namespace, jadi aplikasi tetap memakai tunnel sebagai satu-satunya jalan keluar.

socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork

Proses luar memerlukan root atau kemampuan untuk masuk ke namespace. Jika VPN putus, aplikasi kehilangan jalurnya dan port yang dipublikasikan gagal tertutup, dan itulah perilaku yang Anda inginkan dari sebuah kurungan.

Gunakan pasangan veth saat lebih dari satu port menyeberang

Pasangan veth adalah jawaban yang tepat ketika beberapa port atau protokol harus menyeberang, atau ketika host lain perlu memulai koneksi. Satu ujung tetap di host, ujung lainnya pindah ke namespace, dan /30 kecil memberi kedua sisi alamat yang stabil. Rute host kemudian mengirim alamat namespace melalui pasangan itu.

ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpn
ip addr add 10.77.0.1/30 dev veth0
ip link set veth0 up
ip netns exec vpn ip addr add 10.77.0.2/30 dev veth1
ip netns exec vpn ip link set veth1 up

Jangan menambahkan rute default melalui host kecuali Anda berniat merusak kurungan. Tunnel harus tetap menjadi jalan keluar, jadi hanya alamat layanan yang dipublikasikan yang dapat dijangkau melalui pasangan itu. Beri namespace berkas resolver sendiri juga, karena ip netns exec membaca /etc/netns/vpn/resolv.conf dan tanpanya resolusi nama di dalam kurungan kosong.

Uji dari mesin lain, bukan dari host

Jalankan uji dari mesin kedua, karena host dapat mencapai pendengar lokal melalui jalur yang tidak mengatakan apa pun tentang LAN. Periksa dulu ke apa aplikasi benar-benar terikat di dalam namespace, lalu sambungkan ke alamat yang dipublikasikan dari luar. Mengikat ke setiap alamat di sana tidak melebarkan kurungan, karena wildcard tetap milik namespace dan LAN tidak dapat melihatnya.

ip netns exec vpn ss -lntp

Jika koneksi dari host berhasil dan koneksi dari LAN tidak, bagian yang hilang adalah lompatan atau rute, bukan alamat ikat. Jalankan OpenVPN di dalam namespace alih-alih memindahkan perangkat tun yang hidup ke dalamnya, karena memindahkan antarmuka mematikannya dan dapat menghapus rute yang kemudian tidak dapat Anda perbaiki dari luar. Simpan perintah pemulihan di konsol, bukan di dalam kurungan.

Artikel terkait