Octet

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

Output
$ 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 ACCEPT

iptables -L INPUT -n -v --line-numbers shows the same rules with packet counters and positions.

Changing it

Shell
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 counters

Counters are the best debugging tool: zero them, reproduce, and see which rule's packet count moved.

Persisting

  • Debian and Ubuntu: iptables-persistent restores /etc/iptables/rules.v4 at boot; netfilter-persistent save writes it.
  • RHEL family with iptables-services: /etc/sysconfig/iptables.
  • By hand: iptables-save > file and iptables-restore < file. Restore replaces every table in the file.

Traps

  • Setting the INPUT policy to DROP before adding the SSH allow rule over SSH.
  • Appending an allow rule with -A below an existing catch-all drop. It never matches.
How did you do?