Anda menambahkan aturan untuk lalu lintas VPN di rantai FORWARD, menjalankan permintaan dari mesin Linux yang sama, dan penghitungnya tetap nol. Aturannya kemungkinan besar benar. Paket tidak pernah melewati jalur itu, karena permintaan yang dibuat di mesin itu sendiri tidak diteruskan olehnya. Menelusuri kehidupan paket dari soket sampai kabel menjelaskan mengapa, dan di mana aturan itu seharusnya berada.

Cari tahu di mana paket lahir

Urutan hook Netfilter memisahkan tiga kasus, dan hanya satu di antaranya melibatkan FORWARD:

OriginPathHook that sees it
Local processOUTPUT then POSTROUTINGOUTPUT, POSTROUTING
Addressed to a local servicePREROUTING then INPUTPREROUTING, INPUT
Received for another hostPREROUTING, FORWARD, POSTROUTINGFORWARD

Aplikasi lokal dimulai di jalur OUTPUT, karena kernel sudah menetapkan bahwa paket berasal dari sini dan tidak pernah menjadi kandidat penerusan. Membuat tunnel tidak mengubah klasifikasi itu; tunnel adalah perangkat yang bisa dilalui paket untuk keluar, bukan tahap yang mengubah keluaran lokal menjadi transit.

Dua paket, satu cerita

Setelah tunnel aktif, paket dalam milik aplikasi dan paket luar yang terenkripsi adalah objek yang berbeda. Paket dalam membawa tujuan dan muatan yang dipilih aplikasi. Paket luar membawa ciphertext ke alamat dan port peer, dan itulah yang sebenarnya melintasi antarmuka fisik.

Kebijakan Anda menyangkut salah satunya, dan memilih yang salah adalah penyebab umum sebuah aturan tampak tidak melakukan apa pun. Aturan yang cocok dengan alamat luar peer melihat setiap paket tunnel dengan sama, apa pun yang dilakukan aplikasi di dalam. Aturan yang cocok dengan tujuan dalam melihat lalu lintas yang Anda pedulikan, dan aturan itu hanya akan aktif jika paket tersebut mencapai hook tempat Anda memasang aturan.

Namespace menggeser batas

Kontainer membuat ini lebih sulit tanpa mengubah prinsipnya. Permintaan aplikasi adalah keluaran lokal di dalam namespace jaringan kontainer. Host menerima lalu lintas itu pada antarmuka Ethernet virtual dan dapat meneruskannya, jadi aturan FORWARD di host bisa bermakna meskipun proses yang membuat permintaan tidak pernah menyentuh rantai OUTPUT host.

Sebelum memilih hook, pastikan di mana aturan dan tunnel sebenarnya berada. Tunnel di dalam kontainer, tunnel di host dengan kontainer dirutekan melaluinya, dan tunnel di namespace terpisah adalah tiga topologi berbeda dengan tiga penempatan aturan berbeda. Bacalah aturan di dalam namespace yang memiliki perangkat itu, bukan hanya di namespace default.

Tanyakan apakah Anda perlu mark sama sekali

Jika tujuannya mengirim satu prefiks tujuan melalui tunnel, rute untuk prefiks itu mungkin sudah cukup. Periksa dulu rute yang berlaku, termasuk apa pun yang didorong server: rute default yang dialihkan mengirim jauh lebih banyak lalu lintas melalui VPN daripada kebijakan sempit yang Anda bayangkan, dan sebanyak apa pun mark tidak akan membuat hasilnya sesuai maksud.

Klasifikasi diperlukan ketika keputusan bergantung pada sesuatu yang tidak bisa diungkapkan rute, seperti sumber, pengguna, atau proses. Untuk lalu lintas yang diterima, mark di PREROUTING berfungsi. Untuk lalu lintas lokal, mark harus dilakukan pada tahap keluaran yang dapat memicu pencarian rute baru setelah mark dipasang. Dengan nftables itu adalah rantai bertipe route pada hook keluaran; rantai filter keluaran biasa akan memasang nilainya dan membiarkan rutenya tidak berubah.

Dengan iptables, padanannya berada di susunan mangle OUTPUT, dan syarat yang sama berlaku: keputusan perutean harus ditinjau ulang setelah mark ada. Lalu aturan kebijakan harus mengonsumsi mark dan menunjuk ke tabel yang berisi rute yang bisa dipakai. Memasang mark conntrack adalah operasi ketiga yang terpisah; ia menyimpan nilai pada aliran dan tidak dengan sendirinya menaruh nilai itu pada paket saat ini agar dibaca perutean.

Verifikasi pencarian dan penghitung bersama

nft list ruleset
ip route get 198.51.100.25
ip route get 198.51.100.25 mark 0x1

Alamat dan mark bersifat ilustratif, dan kedua kueri rute menjawab pertanyaan berbeda. Yang kedua menanyakan apa yang akan dilakukan kernel jika sebuah paket membawa mark itu; itu tidak menunjukkan bahwa kumpulan aturan Anda menetapkan satu. Perlakukan sebagai uji hipotesis, bukan bukti kebijakan berfungsi.

Lalu jalankan permintaan yang tidak berbahaya dan amati dua hal sekaligus: penghitung pada hook yang Anda pilih, dan keluaran yang sebenarnya diambil paket. Jika penghitung bergerak dan paket keluar di tempat lain, mark atau tabelnya salah. Jika keduanya tidak bergerak, paket sama sekali tidak mencapai hook itu, dan pertanyaan berikutnya adalah namespace atau jalurnya.

Terakhir, batasi pengujian pada apa yang bisa diungkapkan mekanismenya. Satu rute untuk satu alamat tidak menjadi kebijakan permanen bagi layanan yang alamatnya berputar. Tentukan dulu cakupan paketnya, lalu periksa apakah rancangan perutean dan mark dapat mempertahankan cakupan itu setelah koneksi ulang.

Artikel terkait