UFW is a friendly front-end, but it's built on top of the Linux kernel's actual packet filtering systems — iptables (legacy) and nftables (modern replacement). This guide covers when and how to work with them directly for advanced scenarios UFW doesn't cover.
UFW vs iptables vs nftables
| Tool | Role |
|---|---|
| UFW | Simplified front-end, generates iptables/nftables rules for you |
| iptables | Legacy but still widely used packet filtering framework |
| nftables | Modern replacement for iptables, default on current Debian/Ubuntu kernels |
When to Go Beyond UFW
- Complex NAT/port forwarding rules
- Rate limiting beyond UFW's basic
limitcommand - Custom chains for specific traffic classification
- Fine-grained rule ordering UFW's abstraction doesn't expose directly
Viewing Current iptables Rules
sudo iptables -L -v -n
Basic iptables Rule Structure
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT appends to the input chain, -p tcp --dport 22 matches TCP traffic on port 22, -j ACCEPT is the action (accept the packet).
Common iptables Examples
Allow established connections (required for most rule sets to function correctly):
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Rate-limit new SSH connections:
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
Block a specific IP:
sudo iptables -A INPUT -s 203.0.113.50 -j DROP
Saving iptables Rules Permanently
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
Without this, rules are lost on reboot — a common source of confusion when rules "disappear."
Introduction to nftables (Modern Approach)
sudo nft list ruleset
Basic rule example:
sudo nft add rule inet filter input tcp dport 22 accept
nftables Configuration File
sudo nano /etc/nftables.conf
table inet filter {
chain input {
type filter hook input priority 0;
tcp dport 22 accept
tcp dport 80 accept
tcp dport 443 accept
}
}
sudo systemctl enable nftables
sudo systemctl restart nftables
Checking Which System Is Active
sudo iptables -V
Modern iptables commands are often actually translated to nftables under the hood on current distributions — check the output for confirmation of which backend is in use.
Common Errors
Rules disappear after reboot — not saved persistently; use iptables-persistent or ensure the nftables service is enabled.
Locked out after adding a rule — use your provider's console access; always test rule changes carefully, ideally with a way to revert if something goes wrong.
Best Practices
- Use UFW for standard scenarios — only drop to iptables/nftables directly when you need capabilities UFW doesn't expose
- Always allow established/related connections, or you'll break existing traffic flows
- Save rules persistently, and test carefully before relying on them in production
Related Articles
- How to Configure UFW Firewall on a Linux VPS
- How to Install and Configure Fail2Ban on Ubuntu & Debian
- How to Set Up Port Forwarding on a Linux VPS
