While both iptables -F
and iptables -X
perform cleanup operations, they target different aspects of iptables configuration:
# Flushes all rules in all chains (won't delete chains)
iptables -F
# Deletes all user-defined chains (only works when empty)
iptables -X
The sequence matters because you can't delete (-X) chains that contain rules. A common real-world scenario would be:
# Create custom chain
iptables -N MY_CHAIN
# Add rule to custom chain
iptables -A MY_CHAIN -j DROP
# This would FAIL because chain isn't empty
iptables -X MY_CHAIN
# Correct approach:
iptables -F MY_CHAIN # First flush rules
iptables -X MY_CHAIN # Then delete chain
When dealing with large rule sets, the order becomes particularly important for preventing memory leaks. The proper sequence ensures complete cleanup:
# Recommended cleanup procedure
iptables -F
iptables -X
iptables -Z # Optional: zero counters
In automation scripts, it's wise to include error handling for chain deletion:
#!/bin/bash
# Flush all rules
iptables -F
# Delete user chains with error suppression
iptables -X 2>/dev/null || true
# Alternative for specific chain cleanup
if iptables -L CUSTOM_CHAIN &>/dev/null; then
iptables -F CUSTOM_CHAIN
iptables -X CUSTOM_CHAIN
fi
Built-in chains (INPUT, OUTPUT, FORWARD) can't be deleted with -X, but their policies remain after flushing:
# This will work (flush built-in chain)
iptables -F INPUT
# This will FAIL (can't delete built-in chain)
iptables -X INPUT
When working with iptables for Linux firewall management, two commonly used but distinct commands are:
iptables -F
iptables -X
The -F
flag (or --flush
) removes all rules from the selected chain. If no chain is specified, it flushes all chains in the table.
# Flush all rules in INPUT chain
iptables -F INPUT
# Flush ALL rules in ALL chains (default filter table)
iptables -F
The -X
flag (or --delete-chain
) deletes the specified user-defined chain(s). This command only works on empty chains (already flushed) and cannot delete built-in chains.
# Create a custom chain
iptables -N CUSTOM_CHAIN
# First flush any rules in it
iptables -F CUSTOM_CHAIN
# Then delete the chain
iptables -X CUSTOM_CHAIN
Typical cleanup sequence:
# Step 1: Remove all rules (including from custom chains)
iptables -F
# Step 2: Delete all empty user-defined chains
iptables -X
Imagine you've created a complex firewall setup with multiple custom chains:
iptables -N LOG_DROP
iptables -N PORT_SCAN_PROTECT
iptables -A INPUT -j PORT_SCAN_PROTECT
iptables -A PORT_SCAN_PROTECT -m recent --name ATTACKER --update --seconds 60 -j LOG_DROP
To properly clean this up:
# First flush all rules (including those jumping to custom chains)
iptables -F
# Then verify chains are empty
iptables -L
# Finally delete the custom chains
iptables -X LOG_DROP
iptables -X PORT_SCAN_PROTECT
-F
doesn't affect chain policies (ACCEPT/DROP)-X
fails if chain contains rules or is referenced- Built-in chains (INPUT, OUTPUT, FORWARD) cannot be deleted
- Always specify table (
-t
) when working with non-filter tables
For complex firewall resets including NAT rules:
# Flush and delete in all tables
for table in filter nat mangle raw security; do
iptables -t $table -F
iptables -t $table -X
done