If port 8080 that you opened with ufw allow 8080 is closed again after a server restart, the problem isn't your command; it's that the rule was written to the runtime chain and not saved to the startup file. This text is for when you know which rule you want, and you just need its exact equivalent in another tool or its permanent form.
Three tools, three different mental models
iptables works on linear chains, and each packet is evaluated from top to bottom until the first matching rule. nftables carries the same model forward with tables, sets, and maps, and has been available since kernel 3.13; on most modern distributions, iptables is just a compatibility layer on top of nft. ufw and firewalld are nothing more than rule generators for one of these two.
The practical takeaway: if you run ufw and an iptables -A script at the same time, you have two writers on one chain and your rule order is no longer predictable. Pick one.
Exact command equivalents in iptables, nftables, and ufw
The table below covers the things people actually search for. The nft column is the modern equivalent, not a literal translation.
| Task | iptables | nftables | ufw |
|---|---|---|---|
| View rules | iptables -L -n -v --line-numbers | nft list ruleset | ufw status verbose |
| Open a port | iptables -A INPUT -p tcp --dport 443 -j ACCEPT | nft add rule inet filter input tcp dport 443 accept | ufw allow 443/tcp |
| Rate-limit SSH | iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set | nft add rule inet filter input tcp dport 22 ct state new limit rate 4/minute accept | ufw limit 22/tcp |
| Delete a rule | iptables -D INPUT 3 | nft -a list chain inet filter input then nft delete rule inet filter input handle 12 | ufw delete allow 443/tcp |
| Make persistent | iptables-save > /etc/iptables/rules.v4 | the /etc/nftables.conf file and systemctl enable nftables | automatic in /etc/ufw/ |
One small detail that eats up a lot of time: in nftables, the order of ct state and dport within a rule doesn't matter, but the order of the rules relative to each other does. Same in iptables. If you put a DROP rule before an ACCEPT, the packet never reaches the second line and you won't see anything in the logs unless you've explicitly added -j LOG.
Persistence: where most rules get lost
On Debian and Ubuntu, the iptables-persistent package loads the /etc/iptables/rules.v4 and rules.v6 files at boot. On RHEL and its derivatives, iptables-services and service iptables save. If neither is installed, your rules only live until the next restart.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
systemctl enable --now netfilter-persistent
For nftables, rewrite the /etc/nftables.conf file with nft list ruleset > /etc/nftables.conf and enable the service. Be careful: this command replaces the entire file; if you had comments or includes in it, they're gone.
Where people go wrong
The most common mistake I see in tickets is this: someone runs ufw enable without having run ufw allow 22/tcp first, then goes looking for a network error after SSH drops. The tell is that ping responds (because ICMP is allowed in ufw's default policy) but ssh on port 22 times out. If you've lost access, you can get in through rescue mode and server reinstall and fix the rules.
Evaluation order and custom chains
In iptables you have three built-in chains: INPUT, OUTPUT, and FORWARD. If your server acts as a router or container host, don't underestimate FORWARD; Docker by default injects its own rules into the DOCKER-USER and DOCKER chains, and your FORWARD DROP policy can cut off container traffic. If you run Docker on a VPS, before touching FORWARD, see setting up Docker on a VPS so you know which chains not to touch.
For debugging, counters are your best friend. iptables -L INPUT -n -v shows the packet count for each rule. If a rule has caught zero packets, no traffic has reached it and the problem is elsewhere. In nftables, the equivalent is nft list ruleset with counters, provided the rule was created with counter.
Set the default policy before anything else
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
These four lines are the foundation of any healthy firewall. Don't remove the ESTABLISHED,RELATED line; without it, DNS responses and outbound connections come back and get dropped too. If your server has a MySQL service and you connect to it from outside, instead of opening port 3306 to the entire internet, go with restricting MySQL access.
Which one should I choose
If the server is freshly set up and you don't have a professional sysadmin, choose ufw. Its syntax is short, it saves automatically, and it's enough for 90% of scenarios. If you work on cloud infrastructure and have dynamic rules or large IP sets, nftables is the right choice; a hash-type set lookup over thousands of IPs has constant time complexity, whereas iptables traverses linearly. Keep iptables only when legacy scripts or control panels depend on it.
The cost you have to accept: nftables doesn't work on distributions older than kernel 3.13, and some monitoring tools still parse the output of iptables -L. If your team depends on that output, postpone the migration.
Have a way back before any change
Every time you touch the INPUT chain, schedule an at or screen with a restore command. For example, echo "iptables-restore < /root/rules.backup" | at now + 10 minutes. If you lock yourself out, you're back in ten minutes. This habit will save you more than any documentation.
For servers with heavy traffic, the firewall is only part of the job; if load spikes after applying rules, diagnosing the cause of high server load is the next step. And if you work on a dedicated or cloud server and want to know which network layer is in your hands, see dedicated servers and cloud servers. For initial setup, a Linux host with root access is enough to test these same rules without any intermediary.
Frequently asked questions
Why do iptables rules get wiped after a server restart?
Because the rules only live in kernel memory and haven't been saved to a file. Write them with iptables-save > /etc/iptables/rules.v4 and install and enable the iptables-persistent or netfilter-persistent package. Without this step, every restart or network service reload resets the rules to their initial state.
What's the difference between ufw and iptables, and which is faster?
ufw is a user interface on top of iptables or nftables and doesn't have its own separate filtering engine; so packet processing speed is the same for both. The difference is in management: ufw handles persistence and ordering itself, while iptables gives you full control but you have to write everything by hand.
How do I tell whether a port is actually closed or the service isn't listening?
Test from outside with nc -vz your-server-ip 443. If the connection is refused but ss -tlnp on the server shows the service listening on that port, it's a firewall problem. If the service isn't listening, the firewall is innocent and you need to look at the service.
Is opening a port in the firewall enough for a service to be reachable from outside?
No. Three layers have to line up: the system firewall, the cloud network firewall (security group), and the service itself listening on 0.0.0.0 rather than 127.0.0.1. If the service is bound to localhost, no rule in any firewall will make it reachable from outside.