nftables is the modern replacement for iptables. Learn its table/chain model and write a clean, readable firewall ruleset for a VPS from scratch.
- Topic
- Security
- Read time
- 3 min read
- Covers
- nftables, firewall, security
- Last updated
- July 23, 2026
nftables is the modern packet-filtering framework in the Linux kernel, the official successor to iptables. It's faster, has cleaner syntax, and handles IPv4 and IPv6 in one place. If UFW feels too abstract and iptables feels dated, nftables is the sweet spot for direct control.
The model: tables, chains, rules
Three concepts:
- A table groups related rules for a protocol family (
inetcovers both IPv4 and IPv6). - A chain hooks into a point in packet processing, most importantly
input(traffic arriving at the server). - A rule matches packets and takes an action like
acceptordrop.
The strategy for a server is default-drop: reject everything on input, then explicitly accept only what you need.
Check what's there
sudo nft list rulesetOn a fresh system this may be empty or minimal.
Build a ruleset step by step
Create a table and a filtered input chain with a default drop policy:
sudo nft add table inet filter
sudo nft 'add chain inet filter input { type filter hook input priority 0 ; policy drop ; }'Now add the essential accepts. Keep existing/related connections and loopback:
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo acceptAllow SSH, HTTP and HTTPS:
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } acceptAllow ping (optional but handy for monitoring):
sudo nft add rule inet filter input ip protocol icmp accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 acceptThe cleaner way: a config file
Adding rules one by one is fine for testing, but a config file is easier to read and reload. Write /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif "lo" accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport 22 accept
tcp dport { 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}Load and enable it so it survives reboots:
sudo nft -f /etc/nftables.conf
sudo systemctl enable --now nftablesTest before you trust it
The established,related rule keeps your current SSH session alive while you apply changes, but always verify a new connection works before you disconnect. Open a second terminal and ssh in again. If it fails, use Nxeon's dashboard console to reach the server out-of-band and fix the file.
Restrict a port to one IP
To expose a database only to a trusted address:
sudo nft add rule inet filter input ip saddr 203.0.113.5 tcp dport 5432 acceptEverything else hitting 5432 is dropped by the default policy.
Rate-limit SSH
Slow down brute-force attempts:
sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 4/minute acceptnftables vs UFW — which to use
UFW is perfect when you want simple allow/deny rules and don't care about the internals. nftables is the right call when you want a single readable ruleset, fine-grained matching, unified IPv4/IPv6, or you're building something more complex like NAT. Both ultimately drive the same kernel engine — pick the abstraction that fits how much control you want.
Put this guide to work on Cloud VPS hosting. From $8.88 for the first term, then $12.78 a month.
Nxeon editorial · Straight-talking guides from the team that runs the servers.