Permintaan itu sentiasa varian ayat yang sama: kekalkan VPN untuk pelayaran, tetapi biarkan SSH atau tugas sandaran menggunakan sambungan biasa. Nasihat yang tersebar tentang perkara ini, iaitu memajukan port dengan peraturan NAT iptables, tidak melakukannya. Peraturan NAT menulis semula alamat dan port di dalam aliran; ia tidak pernah memilih antara muka mana paket keluar. Keputusan itu milik carian penghalaan, dan carian penghalaan memerlukan bantuan untuk melihat port.

Mengapa laluan biasa tidak boleh memadankan port

Linux memilih laluan dengan mencari alamat destinasi dalam jadual, selepas jadual calon ditapis melalui peraturan dasar. Peraturan itu boleh memadankan tanda tembok api, alamat sumber, antara muka masuk atau UID. Entri laluan itu sendiri tidak mempunyai medan port, kerana laluan dipilih sebelum pengepala pengangkutan penting.

iproute2 dan kernel masa kini meluaskan pemilih peraturan: ipproto, sport dan dport diterima, jadi ip rule add ipproto tcp dport 22 table 100 menyatakan niat dalam satu baris. Jalankan ip rule add help pada hos sebenar untuk melihat sama ada binaan anda menyenaraikan dport. Jika ya, selesai dengan satu arahan; jika tidak, laluan tanda di bawah ialah yang setara.

Apa pun, peraturan itu hanya penunjuk. Jadual 100 masih memerlukan laluan, dan itulah bahagian yang orang lupa.

Tiga bahagian, atau satu

Bentuk moden ialah peraturan tunggal di atas serta laluan dalam jadual alternatif. Bentuk klasik menambah netfilter di tengah: tandakan paket, kemudian padankan tanda dalam peraturan. Kedua-duanya berakhir pada carian yang sama; bezanya pada tempat port dibaca.

Pendekatan tanda wujud kerana netfilter melihat pengepala pengangkutan dan kod penghalaan secara sejarah tidak. Itulah keseluruhan mekanisme, dan ia menjelaskan mengapa alternatifnya ialah tiga bahagian yang bekerjasama dan bukan satu arahan pintar.

Tiga bahagian mengikut urutan

Pertama, tandakan aliran yang mahu dialihkan, dalam rantai yang berjalan cukup awal supaya tanda itu wujud sebelum keputusan laluan:

nft add table inet vpnexempt
nft 'add chain inet vpnexempt out { type route hook output priority mangle; }'
nft add rule inet vpnexempt out tcp dport 22 meta mark set 0x1

Kedua, hantar paket bertanda ke jadual berasingan:

ip rule add fwmark 0x1/0x1 table 100

Ketiga, beri jadual itu laluan lalai melalui pautan fizikal. Alamatnya contoh sahaja; gantikan dengan milik anda:

ip route add default via 192.168.1.1 dev wlan0 table 100

Langkau langkah ketiga dan paket bertanda tidak menemui laluan dalam jadual 100, jadi ia gagal. Gejalanya kelihatan seperti peraturan itu merosakkan rangkaian, sedangkan sebenarnya ia membuang satu-satunya jalan yang masih ada pada paket itu.

Apa yang menjaganya berfungsi selepas paket pertama

Tanda dikenakan pada paket keluar. Balasan tiba pada antara muka fizikal dengan alamat yang diberikan oleh pautan itu, dan jadual utama mungkin masih mengutamakan terowong untuk destinasi tersebut. Dua mekanisme mengekalkan laluan balasan secara konsisten: peraturan berasaskan sumber untuk alamat pautan, dan penjejakan sambungan yang menyimpan keputusan sepanjang hayat aliran. Menyimpan tanda dalam conntrack dan memulihkannya pada balasan ialah cara biasa untuk menstabilkan pengecualian yang berkeadaan.

Penapisan laluan songsang ialah pembunuh senyap yang lain. Jika kernel mengesahkan laluan balik secara ketat dan balasan tiba pada antara muka yang tidak akan dipilih oleh jadual utama, paket itu digugurkan tanpa mesej. rp_filter nilai lalainya berbeza mengikut distribusi dan sama ada antara muka itu dimajukan, jadi bacalah nilai berkesan dan jangan menganggap ia dimatikan.

Jangan tandakan pengangkutan terowong itu sendiri. Terowong WireGuard atau UDP OpenVPN bukan TCP 22, jadi resipi di atas selamat, tetapi pengecualian yang ditulis sebagai semua kecuali destinasi terowong boleh menangkap paket yang disulitkan dan memecahkan terowong dengan cara yang kelihatan seperti gelung penghalaan.

Periksa dan jangan anggap

Tanya kernel laluan mana yang akan diambilnya, untuk destinasi dan untuk port, kemudian jalankan pemindahan sebenar:

ip route get 203.0.113.10
ip rule show
nft list ruleset

Jika tanda wujud tetapi pembilang tidak pernah bergerak, peraturan itu tidak memadankan. Pembilang ialah perbezaan antara konfigurasi yang anda tulis dan dasar yang kernel laksanakan.

Bilakah ini alat yang salah

Pengecualian berasaskan port memang rapuh. Perkhidmatan berpindah port, HTTP/3 datang sebagai UDP 443, dan satu aplikasi boleh membuka beberapa aliran berlainan jenis. Jika keperluan sebenar ialah program ini menggunakan pautan biasa, lapisan penghalaan ialah tempat yang salah; ruang nama rangkaian atau proksi setiap aplikasi lebih sesuai.

Jika keperluan ialah subnet ini menggunakan pautan biasa, langkau terus semua tanda dan tambah laluan yang lebih khusus. Ia lebih mudah, kelihatan dalam satu jadual, dan orang seterusnya boleh mengauditnya tanpa membaca set peraturan.

Tuliskan yang mana antara tiga keperluan itu benar-benar ada pada anda sebelum menyentuh tembok api. Mekanisme di atas tepat, dan ketepatan yang dikenakan pada lapisan yang salah hanyalah gangguan yang lebih lama.

Artikel berkaitan