iptables configures the Linux packet filter. Rules are checked top to bottom, and the first match wins. Changes are lost at reboot unless you save them, and a wrong default policy over SSH can lock you out, so keep a console or second session available. Modern systems may use the nftables backend (check with iptables -V); these commands work either way.
Click any command to copy it.
List rules
| Command | What it does |
|---|
sudo iptables -L -n -v --line-numbers | List the filter rules with packet counters and rule numbers. |
sudo iptables -S | Print rules in the command form used to create them. |
sudo iptables -t nat -L -n -v | List the NAT table. |
sudo iptables -L INPUT -n --line-numbers | List only the INPUT chain. |
Build a basic input policy
| Command | What it does |
|---|
sudo iptables -A INPUT -i lo -j ACCEPT | Allow loopback traffic. |
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT | Allow replies to connections you started. |
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT | Allow SSH. Do this before changing the policy. |
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT | Allow HTTP and HTTPS. |
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT | Allow ping, rate limited. |
sudo iptables -P INPUT DROP | Destructive: Set the default for incoming traffic to drop. Allow SSH first or you will be locked out. |
Allow and block specific sources
| Command | What it does |
|---|
sudo iptables -A INPUT -s 203.0.113.4 -j ACCEPT | Allow all traffic from one address. |
sudo iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 5432 -j ACCEPT | Allow a subnet to reach PostgreSQL. |
sudo iptables -I INPUT 1 -s 198.51.100.7 -j DROP | Insert a rule at the top to block an address. |
sudo iptables -A INPUT -p tcp --dport 23 -j REJECT | Reject Telnet with an error instead of silently dropping. |
Delete and flush
| Command | What it does |
|---|
sudo iptables -D INPUT 3 | Delete rule number 3 in the INPUT chain. |
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT | Delete a rule by its definition. |
sudo iptables -F | Destructive: Flush all rules in the filter table. With a DROP policy this blocks everything. |
sudo iptables -P INPUT ACCEPT | Reset the incoming default to accept (do this before flushing). |
NAT and forwarding
| Command | What it does |
|---|
sudo sysctl -w net.ipv4.ip_forward=1 | Enable IP forwarding (needed for routing and NAT). |
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE | Share this machine's internet connection (source NAT). |
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80 | Redirect a local port to another. |
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.5:80 | Forward incoming traffic to another host. |
sudo iptables -A FORWARD -d 10.0.0.5 -p tcp --dport 80 -j ACCEPT | Allow the forwarded traffic through the FORWARD chain. |
Logging and persistence
| Command | What it does |
|---|
sudo iptables -A INPUT -j LOG --log-prefix "IPT-DROP: " --log-level 4 | Log packets reaching this rule (place it before a final DROP). |
sudo iptables-save > rules.v4 | Save the current rules to a file. |
sudo iptables-restore < rules.v4 | Load saved rules. |
sudo apt install iptables-persistent | Debian/Ubuntu: restore saved rules at boot. |
sudo netfilter-persistent save | Debian/Ubuntu: save the current rules for the next boot. |
sudo ip6tables -L -n -v | The same commands exist for IPv6 as ip6tables. |
Frequently asked questions
Why did my iptables rules disappear after a reboot?
Rules live in the kernel only. Save them with iptables-save and restore them at boot, for example with iptables-persistent on Debian/Ubuntu.
What is the difference between DROP and REJECT?
DROP silently discards the packet, so the sender waits for a timeout. REJECT sends back an error immediately. DROP gives away less, REJECT is friendlier to legitimate users.
More Networking & Security cheat sheets