Skip to content
DevOps devops networking 5 min read

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 ufw exists — it persists your rules automatically.

Tables, chains, and rules

iptables is organised into three layers. Understanding these three words is the whole game.

LayerWhat it isExample
TableA category of work the firewall doesfilter (allow/block), nat (rewrite addresses), mangle (alter packets)
ChainA checkpoint where packets are inspectedINPUT, OUTPUT, FORWARD
RuleA 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.

ToolWhat it isWhen to use it
ufwHigh-level wrapper over iptablesDaily use. Opening/closing ports on a normal server. Start here.
iptablesThe classic low-level rule toolReading existing rules, debugging, or advanced setups ufw can’t express
nftablesThe modern successor to iptablesNew-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 ufw for 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 -n flag 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-persistent to save them.
  • Treat nftables as the modern path; don’t invest heavily in raw iptables syntax for new work.
Last updated June 15, 2026
Was this helpful?