/flags/iptables/iptables-i-insert-vs-a-append
iptables -I vs -A: insert a rule at the top instead of appending it
- tool
- iptables / nftables
- command
- iptables
- flag
- -I, --insert CHAIN [RULENUM]
- default
- -I without a number inserts at position 1 (the head of the chain); -A always adds at the end
iptables -I INPUT -s 192.0.2.10 -j DROP inserts the rule at the top of the INPUT chain, while iptables -A INPUT ... appends it at the end. The difference matters because netfilter evaluates the rules of a chain in order and stops at the first terminating target (ACCEPT, DROP, REJECT). A blocking rule appended after an existing ACCEPT for the same traffic never runs; inserted before it, it takes effect immediately. -I CHAIN N inserts at position N, shifting the existing rule N and everything after it down by one.
Commands
sudo iptables -L INPUT -n --line-numbers # current order with positions
sudo iptables -I INPUT -s 192.0.2.10 -j DROP # becomes rule 1
sudo iptables -I INPUT 3 -p tcp --dport 8080 -j ACCEPT # becomes rule 3
sudo iptables -A INPUT -j LOG --log-prefix "INPUT-END: " # added after the last ruleRule-position options
| Option | Position | Typical use |
|---|---|---|
| -A, --append CHAIN | End of the chain | Building a rule set in order from a script |
| -I, --insert CHAIN | Position 1 | Emergency block of an address, ahead of all ACCEPT rules |
| -I CHAIN N | Position N | Placing a rule between existing ones |
| -R, --replace CHAIN N | Replaces rule N | Changing a rule in place without reordering |
| -D, --delete CHAIN N or spec | Removes a rule | Undoing a rule by number or by full specification |
| -C, --check CHAIN spec | None | Test whether a rule exists before adding it (idempotent scripts) |
Order pitfalls
- Default policy versus final rule. A chain policy (
-P INPUT DROP) applies only after all rules; an explicit-A INPUT -j REJECTat the end behaves similarly but is a real rule, so later-Arules land after it and never match. Use-Ior insert before it. - Established traffic first. Rule sets usually begin with an
ESTABLISHED,RELATEDaccept (see conntrack --ctstate). Inserting a broad DROP at position 1 puts it above that rule and can cut existing sessions, including your SSH connection. - Scripts that run twice.
-Ain a script that is re-run duplicates rules; check with-Cfirst or flush and rebuild. Deleting a specification that does not exist fails with Bad rule (does a matching rule exist in that chain?). - Positions change. After an insert or delete, numbers shift; list again with
--line-numbersbefore using a position, as shown in list rules with line numbers. - Front ends manage order themselves. ufw, firewalld and Docker insert their own chains; adding rules directly to
INPUTorFORWARDwith-Amay place them after a jump that already decides. Docker documents theDOCKER-USERchain for custom rules.
Blocking a single address end to end is covered in block an IP address, and removing rules in delete a rule.
FAQ
Why does my new iptables rule have no effect?
It was probably appended with -A after a rule that already matches the packet, such as a REJECT-all or an ACCEPT for the same traffic. The first matching terminating rule wins, so insert the rule earlier with -I CHAIN N.
What does iptables -I INPUT without a number do?
It inserts the rule at position 1, the head of the chain. The manual states that 1 is the default when no rule number is given.
How do I see the rule numbers?
iptables -L INPUT -n --line-numbers prints the position of every rule, which is the number -I, -R and -D expect.