23

I have this iptable rules:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-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 80 -j ACCEPT
-A INPUT -j DROP
-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 lines

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

and

-A fail2ban-ssh -j RETURN

seems to be duplicated or written twice. How can I remove the duplicate?

0

7 Answers 7

19

List with line numbers and delete by number.

iptables --line-numbers --list

Then delete one rule using it's line number. Then repeat (line numbers change for following rules when one is deleted so re-list before deleting another).

iptables -D INPUT 6
2
  • 2
    Thanks for this buddy! Will accept this in a matter of minutes. Sep 15, 2014 at 13:48
  • Will this remain persistent after a reboot? Nov 16, 2016 at 17:05
17
iptables-save | uniq | iptables-restore

That is all you need really.

4
  • 6
    AFAICT, this will only remove adjacent duplicates. It will fail to remove non-adjacent duplicates.
    – user61015
    Jan 16, 2018 at 3:36
  • @sampablokuper Then just pipe to sort -u before uniq. Oct 19, 2020 at 21:58
  • 1
    @SkippyleGrandGourou you need to be careful about sorting everything. In the example above, would that not reorder the -j RETURN to before the -s xx.xxx.xx.xx/32 -j REJECT rule, meaning the latter rule would never be seen?
    – mwfearnley
    Oct 29, 2021 at 9:30
  • 1
    @mwfearnley Ha ! You’re right, indeed. Oct 29, 2021 at 13:46
5

If you only want to delete double lines that are directly one after another you can export, unify and reimport it with

mkdir ~/tmp
iptables-save > ~/tmp/iptables.conf
uniq /tmp/iptables.conf > ~/tmp/iptables_new.conf
iptables-restore < ~/tmp/iptables_new.conf

If you want to delete other lines use an editor on ~/tmp/iptables.conf before you reimport it the same way.

Check your new rules with

iptables-save
2
  • If stripping adjacent duplicates is what you seek, then Ricky Neff's answer is more secure, because it avoids exposing firewall the rules to other users who have access to /tmp.
    – user61015
    Jan 16, 2018 at 18:10
  • 1
    thx, you are right, you shouldn't use /tmp cause it is world-readable. I changed it to ~/tmp
    – rubo77
    Jan 16, 2018 at 19:17
3

A comment to fail2ban: fail2ban seems to add its iptables rules itself. So you should not store these rules with e.g. iptables-save. Then after a reboot the rules will be doubled (your saved rule + the rule added by fail2ban).

3

Delete all duplicated lines except COMMIT

/sbin/iptables-save | awk '!COMMIT||!x[$0]++' | /sbin/iptables-restore
2
  • Didn't made any changes with "!COMMIT||" part! But in my iptables-save I had COMMIT only at the bottom. So it worked perfectly. But still wondering what was wrong.
    – user109764
    Feb 10, 2021 at 15:49
  • Shouldn't it be awk '/COMMIT/||... to keep the COMMIT lines? I think !COMMIT would keep every line, since the COMMIT variable is never set.
    – mwfearnley
    Oct 29, 2021 at 9:26
0

I am using such a small bash script which runs through cron.

     #!/bin/bash 
         readarray -t tabl_lines <<< "$(iptables -nL INPUT --line-number | grep "fail2ban-ssh")"
            i=''
            for tline in "${tabl_lines[@]}"
            do 
            #skip the first result
            if [ -n "$i" ]; then
            sudo iptables -D INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
            # if necessary, you can erase and other rules, 
            # because they usually repeat the same number of times
            # sudo iptables -D INPUT -p tcp -m multiport --dports 21 -j fail2ban-vsftpd
save_iptables=yes
            else 
            i=start_remove
            fi
            done
if [ "$save_iptables" == "yes" ]; then
/sbin/service iptables save
fi
0

Kudos to Igor for his script. I feel it's useful:

#!/bin/sh
/sbin/service iptables save
/sbin/iptables-save | awk '/^COMMIT$/ { delete x; }; !x[$0]++' > /tmp/iptables.conf
/sbin/iptables -F
/sbin/iptables-restore < /tmp/iptables.conf
/sbin/service iptables save
/sbin/service iptables restart
if [ -f /tmp/iptables.conf ] ; then /bin/rm -f /tmp/iptables.conf ; fi

Caveat: works only on Redhat / Centos, or other distro with iptables service. Thus my shorted mod for cron/one time use is:

#!/bin/sh
/sbin/iptables-save | awk '/^COMMIT$/ { delete x; }; !x[$0]++' > /tmp/iptables.conf
/sbin/iptables -F
/sbin/iptables-restore < /tmp/iptables.conf
if [ -f /tmp/iptables.conf ] ; then /bin/rm -f /tmp/iptables.conf ; fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.