iptables vs nftables pada Ubuntu: Mana yang digunakan?
Ketahui cara Ubuntu menggunakan iptables untuk menulis peraturan nftables. Semak back end sistem anda dengan arahan iptables --version dan lihat punca konflik Docker.
iptables lawan nftables pada Ubuntu: yang mana satu digunakan oleh pelayan anda?
Pada Ubuntu 20.04 dan versi terkemudian, arahan iptables merupakan antaramuka yang menulis peraturan nftables. Hanya satu penapis paket yang berjalan di dalam kernel, iaitu nftables, dan dua arahan ruang pengguna digunakan untuk memprogramkannya. Baris iptables -A INPUT masih berfungsi seperti biasa, dan peraturan yang diciptanya ialah peraturan nftables yang boleh dipaparkan oleh nft.
Sahkan perkara ini pada pelayan anda sendiri sebelum anda mempercayainya.
iptables -V
sudo update-alternatives --display iptables
sudo nft list rulesetPada Ubuntu 24.04 (iptables 1.8.10, setakat Ogos 2026), iptables -V memaparkan iptables v1.8.10 (nf_tables). Nama di dalam kurungan ialah back end. (nf_tables) bermaksud arahan tersebut berhubung dengan nftables. (legacy) bermaksud back end x_tables yang lama, yang masih dibekalkan oleh Ubuntu sebagai iptables-legacy dan yang dikekalkan oleh kernel sebagai set peraturan yang berasingan sepenuhnya. update-alternatives memaparkan symlink di sebalik pilihan tersebut: link currently points to /usr/sbin/iptables-nft.
Pada VPS baharu yang belum dikonfigurasikan firewall, sudo nft list ruleset tidak memaparkan apa-apa. Output kosong itu ialah garis dasar anda. Tambahkan satu peraturan menggunakan cara lama dan lihat semula.
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo nft list ruleset# Warning: table ip filter is managed by iptables-nft, do not touch!
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
tcp dport 22 counter packets 0 bytes 0 accept
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}Peraturan iptables anda sebenarnya ialah peraturan nftables. iptables-nft menandakan jadual yang diciptanya dan nft memaparkan amaran tersebut apabila ia melihat tanda itu, kerana menyunting jadual sedemikian dengan nft menyebabkan dua alat mengawal peraturan yang sama. Lihat hasil yang dikeluarkan oleh satu arahan: jadual yang tidak anda namakan, dan chain yang tidak anda minta. Itu adalah model lama, dan ia merupakan perkara pertama yang berubah apabila anda menulis nftables secara terus.
Apa yang disembunyikan oleh iptables -L daripada anda
iptables -L hanya memaparkan jadual filter. Peraturan NAT (network address translation) memerlukan iptables -t nat -L, manakala peraturan mangle memerlukan -t mangle. IPv6 berada dalam arahan berasingan, ip6tables, dengan salinan bagi setiap peraturan tersendiri. Oleh itu, sebuah pelayan mungkin kelihatan bersih dalam satu senarai sedangkan terdapat peraturan yang menggugurkan atau menulis semula paket anda daripada jadual yang tidak anda semak.
sudo nft list ruleset mencetak setiap keluarga, setiap jadual, setiap chain dan setiap peraturan dalam satu output. Pada pelayan yang bukan anda bina sendiri, arahan tunggal tersebut merupakan cara terpantas untuk melihat apa yang sebenarnya dimuatkan. Tambahkan -a untuk mencetak handle peraturan, yang anda perlukan untuk memadam satu peraturan sahaja dan bukannya keseluruhan chain.
Dua tabiat perlu diperbetulkan sementara anda berada di sini. iptables -L menyelesaikan alamat dan port kepada nama, jadi pada pelayan dengan resolver yang rosak, ia kelihatan seolah-olah tergantung: gunakan iptables -nvL. Seterusnya, sahkan bahawa back end legasi adalah kosong dengan sudo iptables-legacy -nvL, kerana jika peraturan wujud dalam kedua-dua back end, kernel akan menilai kedua-duanya, dan tiada satu pun senarai yang menunjukkan gambaran keseluruhan kepada anda.
Jadual dan rantaian yang anda cipta, bukan warisi
nftables bermula dengan keadaan kosong. Tiada jadual filter sehingga anda menciptanya, dan perkataan filter hanyalah nama yang anda pilih. Sesuatu rantaian hanya melihat paket apabila anda memberikan jenis, hook, dan keutamaan kepadanya, yang menjadikannya rantaian asas (base chain). Rantaian tanpa ciri tersebut hanya boleh dicapai melalui jump atau goto secara eksplisit, jadi ia tidak memakan sumber sehingga ada sesuatu yang melompat (jump) kepadanya.
Satu lagi perubahan besar ialah keluarga inet. Satu jadual inet mengendalikan IPv4 dan IPv6 dalam peraturan yang sama, yang menghapuskan satu kelas pepijat di mana port ditutup dalam iptables tetapi terbuka luas dalam ip6tables. Ketidakpadanan itu cukup lazim sehingga mempunyai mod kegagalan tersendiri pada kotak ufw.
Berikut ialah set peraturan pelayan yang lengkap. Ia diletakkan dalam /etc/nftables.conf.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
set admin_ips {
type ipv4_addr
flags interval
elements = { 203.0.113.5, 198.51.100.0/24 }
}
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport 22 ip saddr @admin_ips counter accept
tcp dport { 80, 443 } counter accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}Baca baris 2 dua kali. flush ruleset memadamkan setiap jadual pada kotak tersebut, termasuk jadual yang dicipta oleh ufw dan Docker untuk kegunaan mereka sendiri. Teruskan membaca sebelum anda menjalankan ini pada pelayan yang sedang beroperasi.
Peraturan pertama dalam rantaian input melakukan kebanyakan kerja. ct state established,related accept membenarkan balasan kepada sambungan yang anda mulakan untuk masuk semula, jadi baki rantaian hanya perlu membuat keputusan tentang sambungan baharu. ct state invalid drop membuang paket yang tidak sepadan dengan mana-mana sambungan yang diketahui dan tiada permulaan yang sah. Segala-galanya selepas itu ialah lubang eksplisit, dan policy drop mengendalikan selebihnya.
Semak fail tersebut sebelum anda memuatkannya, dan pastikan sesi SSH kedua dibuka semasa anda melakukannya. policy drop ditambah dengan satu kesilapan taip dalam peraturan SSH akan mengunci anda keluar daripada pelayan anda sendiri.
sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list rulesetnft -c -f menghuraikan fail tersebut dan melaporkan ralat tanpa memuatkan apa-apa. Huraian yang bersih tidak akan mencetak sebarang output.
Set menggantikan senarai peraturan yang panjang
tcp dport { 80, 443 } ialah set tanpa nama: satu peraturan dan satu carian, berbanding satu peraturan bagi setiap port. Set bernama seperti admin_ips lebih berkesan, kerana anda boleh mengubahnya semasa firewall sedang berjalan.
sudo nft add element inet filter admin_ips { 203.0.113.9 }
sudo nft list set inet filter admin_ips
sudo nft delete element inet filter admin_ips { 203.0.113.9 }Tiada muat semula, tiada penomboran semula peraturan, dan padanan kekal sebagai satu carian sama ada set tersebut mengandungi lima alamat atau lima puluh ribu. flags interval ialah perkara yang membolehkan set menyimpan julat dan prefiks CIDR (classless inter-domain routing) seperti 198.51.100.0/24. Tanpa flag tersebut, set hanya menerima alamat tunggal, dan pemuatan prefiks akan gagal.
Set juga boleh menamatkan elemennya sendiri.
set banned {
type ipv4_addr
flags timeout
timeout 1h
}Dengan peraturan ip saddr @banned drop, setiap elemen akan membuang dirinya sendiri sejam selepas ia ditambah. Begitulah cara tindakan nftables dalam fail2ban pada Ubuntu 24.04 menyekat sesuatu alamat: ia menambah elemen ke dalam set, bukannya menambah peraturan. Jika port itu sendiri merupakan perkara baharu bagi anda, mulakan dengan apa itu port sebenarnya pada Linux.
Satu perbezaan sering memerangkap pengguna semasa migrasi. nftables tidak mengira paket melainkan anda memintanya. iptables -nvL sentiasa menunjukkan pembilang untuk setiap peraturan. Dalam nftables, hanya peraturan yang membawa kata kunci counter mempunyai nombor, jadi letakkan counter dalam mana-mana peraturan yang anda jangkakan untuk dinyahpepijat kemudian.
Bagaimana hook dan keutamaan menentukan urutan
Base chain menamakan hook, iaitu titik dalam laluan paket di mana ia dijalankan. prerouting dijalankan sebelum keputusan penghalaan (routing decision). input dijalankan untuk paket yang ditujukan kepada mesin ini. forward dijalankan untuk paket yang dihalakan melaluinya. output dijalankan untuk paket daripada proses tempatan. postrouting dijalankan terakhir, tepat sebelum paket keluar.
Keutamaan (priority) menyusun chain di dalam satu hook, dengan nombor terendah didahulukan. nftables memberikan nama kepada nilai klasik: raw ialah -300, mangle ialah -150, dstnat ialah -100, filter ialah 0, srcnat ialah 100. Menulis priority filter; adalah sama dengan menulis priority 0;.
Sekarang bahagian yang menentukan sama ada pencampuran alatan berfungsi. Setiap base chain yang didaftarkan pada satu hook akan dijalankan mengikut urutan keutamaan. Paket yang diterima (accepted) dalam chain anda belum selesai: accept hanya menamatkan chain tersebut, dan paket akan diteruskan ke base chain seterusnya pada hook yang sama. drop adalah muktamad di mana-mana dan menghentikan paket serta-merta. Oleh itu, peraturan yang longgar dalam jadual anda tidak boleh membatalkan tindakan drop dalam jadual ufw, tidak kira yang mana satu dijalankan dahulu, dan accept anda tidak memberikan perlindungan daripada chain yang dijalankan kemudian.
Dua base chain pada hook yang sama dengan keutamaan yang sama akan dijalankan mengikut urutan pendaftaran, yang bergantung pada servis mana yang bermula dahulu. Urutan itu boleh berubah selepas but semula (reboot). Jika anda perlu menjalankan jadual anda sendiri di samping ufw, berikan keutamaan yang berbeza supaya urutannya ditetapkan secara bertulis dan bukannya bergantung pada perlumbaan masa (race condition).
Mengapa tiada peraturan NAT berbalik yang perlu ditulis?
Ini adalah soalan yang paling kerap disalah faham, jadi berikut adalah jawapan terusnya. Penjejakan sambungan (connection tracking) menulis terjemahan berbalik untuk anda. Tiada peraturan kedua yang perlu ditambah.
Jadual nat yang melakukan kedua-dua bahagian tugas VPS biasa kelihatan seperti ini.
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iifname "enp1s0" tcp dport 8080 dnat ip to 10.0.0.5:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.0.0.0/24 oifname "enp1s0" masquerade
}
}Hanya paket pertama sesuatu sambungan dinilai terhadap rantaian nat. Apabila sesuatu peraturan sepadan, kernel menyimpan terjemahan tersebut dalam jadual penjejakan sambungan bersama-sama entri sambungan itu. Setiap paket seterusnya, dalam kedua-dua arah, ditulis semula berdasarkan entri yang disimpan, dan tiada peraturan yang dibaca semula. Pasang alat conntrack dan lihat entri secara langsung.
sudo apt install -y conntrack
sudo conntrack -L -p tcptcp 6 431999 ESTABLISHED src=198.51.100.20 dst=203.0.113.10 sport=54321 dport=8080 src=10.0.0.5 dst=198.51.100.20 sport=80 dport=54321 [ASSURED] mark=0 use=1Baca ia sebagai dua tuple. Empat medan pertama ialah sambungan seperti yang dihantar oleh klien, ditujukan kepada 203.0.113.10:8080, alamat awam anda. Empat medan kedua ialah balasan yang dijangkakan oleh kernel, yang telah diterbalikkan dan diterjemahkan, datang daripada 10.0.0.5:80, backend sebenar. Tuple kedua itu adalah peraturan berbalik tersebut. Kernel menulisnya apabila paket pertama sepadan.
Oleh itu, jangan tulis peraturan untuk arah balasan. Ia tidak boleh sepadan, kerana paket balasan tergolong dalam sambungan yang telah diwujudkan dan tidak akan sampai ke rantaian nat, dan jika ia entah bagaimana sepadan, anda akan menterjemahkan paket yang telah pun dibetulkan oleh kernel.
Di mana penulisan semula perlu diletakkan adalah berdasarkan mekanisme yang sama. Terjemahan destinasi perlu dijalankan dalam prerouting, sebelum keputusan penghalaan (routing decision), kerana penghalaan mesti melihat destinasi baharu atau paket akan pergi ke tempat yang salah. Trafik yang dijana oleh kotak itu sendiri dikendalikan dalam cangkuk output atas sebab yang sama. Terjemahan sumber, termasuk penulisan semula port sumber, perlu dijalankan dalam postrouting, selepas penghalaan memilih antara muka keluar. masquerade mengambil alamatnya daripada antara muka tersebut, dan antara muka itu tidak diketahui sehingga penghalaan dijalankan.
Itulah sebabnya peraturan seperti ini diletakkan di hujung laluan dan bukan di tempat lain.
ip saddr 10.0.0.0/24 oifname "enp1s0" snat ip to 203.0.113.10:20000-30000Julat port menulis semula port sumber bersama-sama alamat sumber, iaitu apa yang anda perlukan apabila banyak klien dalaman berkongsi satu alamat awam dan port sumber mereka bertembung. Balasan tiba yang ditujukan kepada port dalam julat tersebut, conntrack memadankannya dengan entri tersebut, dan port sumber asal dikembalikan sebelum paket dihantar. Sekali lagi, tiada peraturan kedua.
Satu akibat praktikal: menukar peraturan NAT tidak mengalihkan sambungan yang sedia ada, kerana terjemahannya sudah disimpan. Ia mengekalkan kelakuan lama sehingga entri tersebut tamat tempoh. sudo conntrack -D -p tcp --dport 8080 memadamkan entri yang sepadan dan sudo conntrack -F memadamkan kesemuanya. Berhati-hati dengan arahan kedua pada kotak NAT, kerana terjemahan yang disimpan itulah yang memastikan sambungan semasa kekal hidup, jadi memadamkannya akan memutuskan setiap sambungan melalui kotak tersebut serta-merta.
ufw dan Docker masing-masing menulis peraturan mereka sendiri
ufw ialah antaramuka kepada iptables, yang pada Ubuntu merupakan antaramuka kepada nftables. Oleh itu, kotak ufw mempunyai jadual ip filter yang penuh dengan rantaian bernama ufw-before-input, ufw-user-input dan sebagainya, serta salinan ip6 filter bagi struktur yang sama. Periksa dengan sudo nft list ruleset | grep ufw. Rantaian tersebut dijana daripada fail dalam /etc/ufw, dan ufw reload menulis semula fail tersebut dari awal, itulah sebabnya peraturan iptables yang ditulis secara manual dan ditambah di atas akan hilang pada muat semula seterusnya. Asas ufw untuk VPS merangkumi susun atur fail tersebut.
Docker memprogramkan firewall itu sendiri dan tidak merujuk kepada ufw. Menerbitkan port dengan -p 80:80 akan menulis peraturan DNAT ke dalam jadual nat dan satu accept ke dalam laluan forward, dan kedua-duanya berjalan sebelum rantaian pengguna ufw. Hasilnya mengejutkan semua orang sekali: ufw deny 80 dimuatkan, namun kontena tersebut masih boleh dicapai dari internet. Penyelesaiannya terletak pada rantaian DOCKER-USER yang ditinggalkan oleh Docker untuk peraturan anda, dan mengapa kontena Docker mengabaikan ufw membincangkan perkara ini dengan terperinci. Lihat apa yang ada pada kotak anda dengan sudo nft list ruleset | grep -i docker.
Sekarang baca semula baris flush ruleset daripada konfigurasi di atas. Ia memadamkan setiap jadual, termasuk jadual yang diuruskan oleh kedua-dua alatan tersebut. Pada hos Docker, port yang diterbitkan akan berhenti berfungsi sehingga sudo systemctl restart docker membina semula rantaian tersebut. Baris tunggal itu merupakan cara paling biasa orang ramai menyebabkan servis mereka sendiri terputus talian semasa mengemaskan firewall.
Peraturan yang kekal selepas but semula
Tiada set peraturan yang kekal dengan sendirinya. Kernel akan melupakan segala-galanya semasa penutupan sistem, dan setiap pihak menyelesaikannya dengan pakej yang berasingan.
Bagi nftables, /etc/nftables.conf dibaca oleh nftables.service. Ubuntu menghantar servis tersebut dalam keadaan dinyahdayakan, jadi semak statusnya sebelum anda mempercayainya.
systemctl is-enabled nftables
sudo nft -c -f /etc/nftables.conf
sudo systemctl enable --now nftablesBagi iptables, pakejnya ialah iptables-persistent, yang memasang netfilter-persistent serta menyimpan peraturan ke /etc/iptables/rules.v4 dan /etc/iptables/rules.v6.
sudo apt install -y iptables-persistent
sudo netfilter-persistent saveJangan jalankan kedua-duanya serentak. Dua fail yang masing-masing mendakwa mengandungi firewall akan menjadi tidak selari, dan fail yang dimuatkan terakhir akan menang dengan cara yang tidak dapat diramalkan oleh sesiapa pun hanya dengan membaca fail tersebut.
Terdapat perangkap berkaitan apabila melakukan dump set peraturan yang sedang berjalan. sudo nft -s list ruleset > /etc/nftables.conf menangkap segala-galanya yang dimuatkan pada saat itu, termasuk jadual ufw dan jadual Docker. Jika anda memulihkan data tersebut semasa but, anda akan mendapat salinan beku bagi peraturan yang sepatutnya dibina sendiri oleh alatan tersebut, kemudian satu salinan kedua akan muncul sebaik sahaja alatan itu bermula. Lakukan dump hanya pada jadual anda sendiri dengan sudo nft -s list table inet filter. Flag -s akan mengecualikan pembilang (counters), yang tidak sepatutnya berada dalam fail konfigurasi.
Patutkah anda menghidupkan ufw pada VPS anda?
Biarkan ufw seperti sedia ada kecuali anda memerlukan sesuatu yang tidak dapat dikendalikan olehnya. ufw meliputi tugas VPS biasa: polisi lalai (default deny) dengan beberapa port terbuka. Menggantikannya dengan set peraturan yang ditulis sendiri tanpa sebab yang kukuh hanya akan memberikan anda firewall yang sama, tetapi dengan beban penyelenggaraan tambahan.
Gunakan kaedah natif apabila keperluan anda berada di luar model ufw: NAT dan port forwarding, set yang anda kemas kini semasa runtime, satu peraturan yang merangkumi kedua-dua keluarga alamat, atau keutamaan chain yang anda tentukan sendiri. Itu adalah sebab yang munasabah, dan ufw tidak mempunyai cara untuk melaksanakannya.
Jika anda memilih kaedah natif, lakukan sepenuhnya. Jalankan sudo ufw disable dan sudo systemctl disable --now ufw, sahkan dengan sudo nft list ruleset bahawa jadualnya telah dipadamkan, kemudian muatkan fail anda sendiri. Pelayan yang menjalankan ufw dan jadual yang ditulis sendiri secara serentak masih akan membenarkan trafik, tetapi polisi sebenar kini merupakan gabungan dua set peraturan yang dinilai mengikut urutan permulaan servis, dan tiada sesiapa yang membaca fail tersebut dapat menentukan tindakan sebenar pelayan itu.
Memindahkan set peraturan iptables sedia ada
iptables-translate menukar satu peraturan dan mencetak bentuk nftablesnya. Ia tidak mengubah apa-apa pada pelayan.
iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPTnft add rule ip filter INPUT tcp dport 22 counter acceptiptables-restore-translate -f /etc/iptables/rules.v4 melakukan perkara yang sama untuk keseluruhan set peraturan yang disimpan. Anggap outputnya sebagai draf pertama. Penukaran ini bersifat mekanikal dan dilakukan peraturan demi peraturan, jadi anda akan mendapat semula nama jadual dan rantaian yang lama, dua set peraturan berasingan untuk IPv4 dan IPv6, serta tiada set yang menjadikan proses pemindahan ini berbaloi. Tulis semula sebagai satu jadual inet secara manual, kemudian semak dengan nft -c -f sebelum ia digunakan pada pelayan sebenar.
Alamat dalam contoh ini diambil daripada julat dokumentasi 203.0.113.0/24 dan 198.51.100.0/24, manakala enp1s0 ialah nama antara muka. Gunakan milik anda daripada ip route show default dan ip -br addr dan bukannya menyalin milik saya, kerana imej Ubuntu semasa jarang menamakan apa-apa sebagai eth0.
FAQ
Adakah iptables sudah tidak digunakan lagi (deprecated) pada Ubuntu?
Perintah ini tidak akan dibuang dan ia masih berfungsi pada Ubuntu 24.04. Perubahan yang berlaku adalah pada bahagian dalamannya: iptables ialah antaramuka yang menulis peraturan nftables melalui back end iptables-nft. Semak sistem anda dengan iptables -V, yang akan mencetak iptables v1.8.10 (nf_tables) pada versi 24.04. Back end lama x_tables masih disertakan sebagai iptables-legacy, dan ia menyimpan set peraturan yang berasingan sepenuhnya, jadi letakkan peraturan dalam satu back end sahaja dan jangan gunakan kedua-duanya.
Adakah saya perlukan peraturan kedua untuk membatalkan NAT pada arah balik?
Tidak. Penjejakan sambungan (connection tracking) menyimpan terjemahan tersebut apabila paket pertama sesuatu sambungan sepadan dengan peraturan nat, dan setiap paket seterusnya dalam kedua-dua arah akan ditulis semula berdasarkan entri yang disimpan itu. sudo conntrack -L menunjukkannya sebagai dua tupel bagi setiap sambungan: arah asal, kemudian balasan yang telah diterbalikkan. Peraturan yang ditulis untuk arah balik tidak akan membantu, kerana paket balasan tidak akan sampai ke chain nat.
Bolehkah saya menjalankan ufw dan peraturan nftables saya sendiri pada masa yang sama?
Ia boleh berfungsi, tetapi anda akan menghadapi masalah. Setiap base chain pada hook akan berjalan, jadi polisi yang aktif adalah gabungan kedua-dua set peraturan, disusun mengikut keutamaan dan, jika keutamaan sama, mengikut servis mana yang bermula dahulu. drop dalam mana-mana satu set adalah muktamad, dan accept dalam peraturan anda tidak menghalang set yang satu lagi daripada menggugurkan (drop) paket yang sama. Pilih satu alat sahaja. Jika anda memilih nftables, nyahdayakan ufw terlebih dahulu dan pastikan jadualnya telah hilang daripada sudo nft list ruleset.
Bagaimanakah cara untuk memastikan peraturan nftables kekal selepas but semula (reboot) pada Ubuntu?
Letakkan set peraturan dalam /etc/nftables.conf, semak dengan sudo nft -c -f /etc/nftables.conf, kemudian jalankan sudo systemctl enable --now nftables. Servis ini tidak diaktifkan secara lalai, jadi systemctl is-enabled nftables perlu dijalankan sekali. Apabila anda menjana fail tersebut, dump hanya jadual anda sendiri dengan sudo nft -s list table inet filter, kerana dump list ruleset penuh juga akan menangkap jadual yang diuruskan oleh ufw dan Docker untuk kegunaan mereka sendiri.