How to Clean Up Duplicate iptables Rules: A Practical Guide for Linux System Administrators


1 views

When examining your iptables configuration, I noticed two types of duplicate rules:

-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
(duplicated)
-A fail2ban-ssh -j RETURN
(duplicated)

These duplicates serve no functional purpose and can actually:

  • Reduce firewall performance by adding unnecessary processing steps
  • Make rule maintenance more difficult
  • Potentially cause confusion during troubleshooting

While the duplicates won't break your firewall (iptables processes rules sequentially), they create technical debt in your configuration. The fail2ban-ssh chain has three rules:

-A fail2ban-ssh -s xx.xxx.xx.xx/32 -j REJECT --reject-with icmp-port-unreachable
-A fail2ban-ssh -j RETURN
-A fail2ban-ssh -j RETURN

The duplicate RETURN rules are particularly problematic because:

  1. The first RETURN will exit the chain
  2. The second RETURN will never be reached
  3. This indicates potential configuration drift over time

Here's how to properly clean up your iptables configuration:

Method 1: Manual Deletion

# List all rules with line numbers
iptables -L INPUT --line-numbers
iptables -L fail2ban-ssh --line-numbers

# Delete specific duplicates (example for line 2)
iptables -D INPUT 2
iptables -D fail2ban-ssh 3

Method 2: Using iptables-save/restore

# Save current rules
iptables-save > current.rules

# Edit the file manually (remove duplicates)
vi current.rules

# Restore cleaned rules
iptables-restore < current.rules

To maintain clean iptables configurations:

# Create a wrapper script that checks for existing rules before adding
#!/bin/bash
rule="$@"
if ! iptables -C $rule 2>/dev/null; then
    iptables $rule
fi

For critical systems, consider implementing configuration management with tools like:

  • Ansible iptables modules
  • Puppet firewall resources
  • Chef iptables cookbooks

After cleaning up, verify your configuration:

# Check for remaining duplicates
iptables-save | grep -A1 'fail2ban-ssh' | sort | uniq -d

# Test SSH connection
telnet localhost 22

Remember to test your firewall thoroughly after making changes, especially on production systems.


When examining your current iptables configuration, we notice two identical rules appearing consecutively:

-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh

And similarly in the fail2ban-ssh chain:

-A fail2ban-ssh -j RETURN
-A fail2ban-ssh -j RETURN

While these duplicates don't cause functional issues (as iptables processes rules sequentially), they create unnecessary overhead:

  • Increased memory usage for rule storage
  • Slower rule processing during packet matching
  • More difficult configuration maintenance

Here's the proper way to remove duplicates while maintaining functionality:

# First, flush all current rules
iptables -F
iptables -X fail2ban-ssh

# Then recreate the rules without duplicates
iptables -N fail2ban-ssh
iptables -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -j DROP

# Add fail2ban-ssh chain rules
iptables -A fail2ban-ssh -s xx.xxx.xx.xx/32 -j REJECT --reject-with icmp-port-unreachable
iptables -A fail2ban-ssh -j RETURN

After applying these changes, verify with:

iptables -L -n --line-numbers
iptables -L fail2ban-ssh -n --line-numbers

For larger rulesets, consider this bash script to detect duplicates:

#!/bin/bash
iptables-save | awk '/^-[A-Z]/ {print} /^-A/ {rule=$0; sub(/ -A /," -A "); if (seen[rule]++) print "# DUPLICATE: "rule; else print}'

Best practices to maintain clean iptables configurations:

  • Use configuration management tools (Ansible, Puppet, Chef)
  • Store rules in version-controlled files
  • Implement pre-commit hooks to check for duplicates
  • Use iptables-apply for atomic changes