Mengapa aturan iptables Anda tidak pernah melihat lalu lintas VPN yang dijembatani
Frame yang dijembatani dapat melewati rantai IP yang Anda pantau. Bandingkan keluarga bridge asli dengan br_netfilter lama sebelum menambahkan aturan lain.
Dua mesin virtual di host yang sama mencapai LAN melalui jembatan, dan aturan yang ditempatkan di rantai ip forward menunjukkan penghitung yang tidak pernah bergerak. Frame-nya nyata, lalu lintasnya lewat, dan aturan itu memang tidak ada di jalurnya. Membandingkan dua cara Linux memperlihatkan lalu lintas yang dijembatani menjelaskan kesunyian ini, dan juga menjelaskan mengapa memuat satu modul lama adalah jawaban yang lebih buruk daripada kelihatannya.
Dua jalur melalui satu host
Sebuah paket dapat meninggalkan host ini melalui dua cara yang sangat berbeda, dan perbedaannya menentukan hook mana yang melihatnya. Jika tujuan berada di luar port fisik dan frame dialihkan di antara dua port jembatan, host meneruskan frame Ethernet; kode perutean tidak dipanggil, dan tidak terjadi lompatan yang dirutekan. Jika tujuannya adalah host itu sendiri, atau jaringan yang dicapai melalui antarmuka terowongan, paket dirutekan dan hook lapisan IP memang berlaku. Ingatlah percabangan ini, karena setiap pertanyaan berikutnya tentang rantai dan keluarga mengikuti jalur mana yang diambil sebuah frame.
Pembedaan itu adalah seluruh cerita di balik aturan yang tidak menghitung apa pun. Frame yang dijembatani dari veth9a1 ke enp3s0 melintasi jembatan, bukan tumpukan IP, sehingga rantai ip forward tidak melihat apa pun untuk dicocokkan. Nama antarmuka dalam contoh lama tidak menentukan jalur mana yang Anda miliki, dan karena itu langkah pertamanya adalah melihat topologi, bukan kumpulan aturan.
Terowongan menambahkan kasus ketiga yang layak diberi nama. Perangkat TUN mengirimkan paket IP ke host, sehingga paket itu dirutekan dan benar-benar melewati rantai IP, sedangkan perangkat TAP yang terhubung ke jembatan mengirimkan frame dan berperilaku seperti kasus jembatan. Jenis perangkatnya, bukan nama produknya, yang menentukan.
Bandingkan dua keluarga yang dapat melihat frame yang dijembatani
Linux mendukung penyaringan jembatan asli melalui keluarga bridge nftables, dan tidak memerlukan modul lama untuk memeriksa dan menjatuhkan frame saat melintas. Dokumentasi jembatan milik kernel sendiri memberikan rekomendasi itu secara langsung, yang layak diketahui sebelum hasil pencarian menyuruh Anda memuat modul.
| Observation point | What it sees | What it costs |
|---|---|---|
nftables bridge family chains | Ethernet frames forwarded between bridge ports, in both directions | Rules must be written in bridge syntax with link-layer matches |
Legacy br_netfilter plus an ip chain | Bridged IPv4 and IPv6 packets, re-exposed through IP-layer hooks | Existing host rules may begin matching traffic they never saw before |
inet chain for routed traffic | Packets the host routes, including traffic arriving from a TUN device | No visibility into purely switched frames |
Memakai perintah nft alih-alih iptables tidak dengan sendirinya menempatkan aturan di keluarga yang tepat. Rantai yang dideklarasikan di keluarga bridge melihat frame; rantai yang dideklarasikan di ip, ip6, atau inet tidak melihatnya, apa pun biner yang membuatnya. Keluarga adalah sifat rantai, bukan sifat alat yang mengetiknya.
Jalur lama bekerja berbeda, dan itulah alasan untuk membandingkan alih-alih memilih pihak karena kebiasaan. Memuat br_netfilter dan mengaktifkan pengaturan bridge-nf-call kembali memperlihatkan lalu lintas IPv4 dan IPv6 yang dijembatani melalui hook lapisan IP, sehingga aturan iptables biasa akhirnya dapat mencocokkannya. Frame-nya tidak berubah; himpunan hook yang dilaluinya berubah, yang berarti setiap aturan host yang ada kini punya audiensi baru.
Baca jalur yang berlaku sebelum menambahkan aturan
Tiga perintah menetapkan posisi Anda: apa yang terhubung ke jembatan, apakah modul lama aktif, dan rantai apa yang sudah ada di keluarga bridge. Jalankan sebelum menulis apa pun, karena jawabannya menentukan desain mana yang Anda perluas. Melewati langkah ini adalah cara sebuah aturan yang benar berakhir di rantai yang tidak dilalui apa pun.
bridge link show
lsmod | grep br_netfilter
nft list ruleset | grep -A4 "chain forward"
Keluarannya memisahkan kasus dengan rapi. Port yang terdaftar di bawah jembatan memberi tahu Anda antarmuka mana yang dialihkan; hasil lsmod yang kosong berarti tidak ada visibilitas lapisan IP atas frame yang dijembatani sama sekali; rantai forward keluarga bridge yang sudah ada berarti pemilik kebijakan sudah ada dan aturan Anda tempatnya di sana, bukan di rantai baru miliknya sendiri.
Lalu tambahkan satu aturan yang mudah dibaca kembali, dengan penghitung dan tanpa mengubah putusan, dan alirkan satu aliran perwakilan melewati jembatan. Penghitung yang bergerak membuktikan frame mencapai aturan. Itu saja yang dibuktikannya, jadi lanjutkan dengan jalur yang ditolak juga, karena kebijakan yang menerima semuanya juga menghasilkan penghitung yang bergerak.
nft add rule bridge filter forward iifname "veth9a1" oifname "enp3s0" counter acceptDi mana modul lama mengubah perilaku
Mengaktifkan jalur lama pada jembatan yang berjalan bukan tindakan netral untuk menambah visibilitas. Aturan yang sebelumnya tidak terjangkau bagi lalu lintas yang dijembatani menjadi terjangkau, termasuk aturan host yang ditulis untuk antarmuka lain, dan kebijakan drop bawaan di rantai ip forward dapat tiba-tiba berlaku pada frame yang tadinya lewat tanpa tersentuh. Pada host yang dikelola melalui jembatan itu, hasilnya adalah terkunci tanpa konsol. Ini bukan mode kegagalan hipotetis; ini konsekuensi biasa dari memperluas himpunan hook pada mesin yang Anda capai melalui jalur yang baru saja Anda perluas.
Urutan yang lebih aman adalah memutuskan keluarga mana yang memiliki kebijakan, menulis aturannya di sana, dan menyimpan jalur pemulihan yang independen sebelum mengubah sysctl apa pun. Jika dua keluarga sama-sama memegang aturan, dokumentasikan mana yang berwenang; dua kebijakan yang bertumpang tindih adalah cara sebuah paket diterima di satu tempat dan dijatuhkan di tempat lain tanpa satu berkas pun untuk dibaca.
Isolasi itu sendiri tetap memerlukan desain yang lengkap. Mengizinkan satu sumber ke satu tujuan hanya membuktikan satu aliran bekerja, sedangkan persyaratannya biasanya adalah VM tidak dapat mencapai tetangganya atau host. Penghitung pada aturan penolakan lebih penting daripada penghitung pada aturan penerimaan, karena penghitung penerimaan adalah yang sudah Anda harapkan bergerak.
Terakhir, pisahkan kasus masukan host. Lalu lintas yang dialamatkan ke IP jembatan itu sendiri tiba di input, bukan forward, dan aturan di forward tidak akan pernah melihatnya, apa pun keluarga yang Anda pilih. Tiga kasus, dua keluarga, satu pelajaran: jalur menentukan hook, dan hook menentukan apakah aturan Anda ada sama sekali.