iptables Basics
When you run ufw to allow or block traffic on an Ubuntu server, something deeper is doing the real work behind the scenes. That something is iptables — the classic command-line tool for controlling the Linux kernel’s built-in firewall. A firewall is just software that decides which network packets (small chunks of data travelling over the network) are allowed in or out of your machine. This page explains how iptables thinks so that the rules you see make sense — even though, for everyday work, we’ll recommend you stick with ufw.
What iptables actually controls
iptables is a user-facing tool that talks to a part of the Linux kernel called netfilter (the actual firewall engine baked into Linux). You can think of it like this: netfilter is the security guard standing at the door, and iptables is the rulebook you hand the guard. The guard inspects every packet and checks it against the rulebook to decide what to do.
Every packet flowing into, out of, or through your server passes through netfilter. iptables lets you write the rules that say “allow this”, “block that”, or “rewrite this address”. ufw (Uncomplicated Firewall) is simply a friendlier wrapper that writes iptables rules for you, so you don’t have to learn the raw syntax.
Important: iptables rules are not saved across reboots by default. If you edit raw iptables rules and reboot, they vanish. This is one big reason
ufwexists — it persists your rules automatically.
Tables, chains, and rules
iptables is organised into three layers. Understanding these three words is the whole game.
| Layer | What it is | Example |
|---|---|---|
| Table | A category of work the firewall does | filter (allow/block), nat (rewrite addresses), mangle (alter packets) |
| Chain | A checkpoint where packets are inspected | INPUT, OUTPUT, FORWARD |
| Rule | A single condition + action | ”If port 22, then ACCEPT” |
The most common table is filter — it decides whether to allow or block traffic. Inside it live three built-in chains:
- INPUT — packets arriving for this server (e.g. someone connecting to your SSH or web server).
- OUTPUT — packets leaving this server (e.g. your server downloading an update).
- FORWARD — packets passing through this server to somewhere else (used when the machine acts as a router).
A packet walks down the rules in a chain one by one, top to bottom. The first rule that matches decides its fate. If no rule matches, the chain’s policy (its default action) applies.
ACCEPT and DROP — the two core actions
Each rule ends in a target, which is the action taken when the rule matches. The two you’ll see most often are:
- ACCEPT — let the packet through.
- DROP — silently discard the packet, as if the server never received it. The sender gets no reply at all.
There’s also REJECT, which discards the packet but sends back a polite “connection refused” message. DROP is stealthier (attackers can’t even tell the port exists), while REJECT is faster for legitimate clients because they don’t have to wait for a timeout.
A good firewall follows a default-deny model: drop everything, then explicitly accept only what you need (like SSH on port “22” and HTTPS on port “443”). This is exactly what ufw sets up for you.
Listing the current rules
The single most useful command is listing what rules are active. You almost always need sudo because firewall rules are privileged.
sudo iptables -L -n -v
The flags mean: -L list rules, -n show numbers instead of resolving names (much faster), and -v verbose (show packet counts).
Output:
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
120 9600 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
2048 150K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
88 5280 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
Chain FORWARD (policy DROP 0 packets, 0 bytes)
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
Reading this: the INPUT chain’s policy is DROP (default-deny), but three rules punch holes in it — traffic on the loopback interface (lo, the server talking to itself), TCP to port “22” (SSH), and TCP to port “443” (HTTPS). Everything else is dropped. The dpt: part means “destination port”.
To see the NAT table (which ufw and Docker use for address rewriting), add -t nat:
sudo iptables -t nat -L -n
When to use iptables vs ufw vs nftables
This is the practical decision, so here it is side by side.
| Tool | What it is | When to use it |
|---|---|---|
| ufw | High-level wrapper over iptables | Daily use. Opening/closing ports on a normal server. Start here. |
| iptables | The classic low-level rule tool | Reading existing rules, debugging, or advanced setups ufw can’t express |
| nftables | The modern successor to iptables | New-style firewalls; it’s the long-term direction on modern Linux |
For almost every reader of this site, the answer is ufw. See the ufw firewall guide for the commands you’ll actually type.
A note on nftables
Since 2018, Linux has shipped nftables — a newer, cleaner firewall framework meant to replace iptables. On Ubuntu 22.04 and 24.04, the iptables command you run is usually iptables-nft, a compatibility shim that translates your old-style commands into nftables under the hood. So even when you type iptables, nftables may be doing the real work.
You don’t need to learn nftables syntax yet. But know that it exists, that it’s the future, and that ufw works happily on top of either one. When you eventually outgrow ufw, nftables (nft) is where to invest your learning, not raw iptables.
Best Practices
- Use
ufwfor everyday firewall management — it persists rules across reboots and is far harder to lock yourself out with. - Adopt a default-deny policy: block everything, then allow only the specific ports you need (SSH, HTTP/HTTPS).
- Always keep an SSH rule before tightening anything, or you can lock yourself out of a remote server. Test with a second session open.
- Prefer reading rules with
sudo iptables -L -n -v— the-nflag avoids slow DNS lookups and shows real port numbers. - Remember raw iptables rules are not saved on reboot; if you must use them directly, install
iptables-persistentto save them. - Treat nftables as the modern path; don’t invest heavily in raw iptables syntax for new work.