How does iptables evaluate rules, and how do you add, remove and save them safely?
Show the answer
Say this first
Rules in a chain are checked top to bottom and the first rule with a terminating target (ACCEPT, DROP,
REJECT) wins. If nothing matches, the chain's policy applies; only built-in chains have a policy, ACCEPT or
DROP. -A appends to the bottom, -I inserts at the top or at a position, -D deletes by spec or line
number. Rules live in kernel memory, so they need iptables-save and a restore at boot to persist.
Go deeper
Reading a chain
$ sudo iptables -S INPUT
-P INPUT DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPTiptables -L INPUT -n -v --line-numbers shows the same rules with packet counters and positions.
Changing it
iptables -I INPUT 3 -p tcp -s 10.0.50.0/24 --dport 9100 -j ACCEPT # insert as rule 3
iptables -D INPUT 3 # delete rule 3
iptables -Z INPUT # zero the countersCounters are the best debugging tool: zero them, reproduce, and see which rule's packet count moved.
Persisting
- Debian and Ubuntu:
iptables-persistentrestores/etc/iptables/rules.v4at boot;netfilter-persistent savewrites it. - RHEL family with
iptables-services:/etc/sysconfig/iptables. - By hand:
iptables-save > fileandiptables-restore < file. Restore replaces every table in the file.
They will ask next
DROP or REJECT?
REJECT answers: an ICMP port unreachable by default, or a TCP reset with
--reject-with tcp-reset. The client fails fast. DROP is silent and the client waits for its timeout. I use REJECT inside the network so applications fail quickly, and DROP at the internet edge.How do you change rules on a remote box without locking yourself out?
Keep the ESTABLISHED rule at the top so the current SSH session survives, and use a rollback:
iptables-applyreverts unless you confirm, or schedule a restore of the saved rules a few minutes ahead and cancel it once you have checked access.
Traps
- Setting the INPUT policy to DROP before adding the SSH allow rule over SSH.
- Appending an allow rule with
-Abelow an existing catch-all drop. It never matches.