25

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?

Giacomo1968
  • 3,542
  • 27
  • 38
Leandro Garcia
  • 473
  • 2
  • 8
  • 15

7 Answers7

20

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
Giacomo1968
  • 3,542
  • 27
  • 38
Brian
  • 3,476
  • 18
  • 16
20
iptables-save | uniq | iptables-restore

That is all you need really.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
Ricky Neff
  • 301
  • 2
  • 3
6

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
rubo77
  • 2,469
  • 4
  • 34
  • 66
  • If stripping adjacent duplicates is what you seek, then Ricky Neff's [answer](https://serverfault.com/a/890065/) is more secure, because it avoids exposing firewall the rules to other users who have access to `/tmp`. –  Jan 16 '18 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 '18 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).

halboffen
  • 39
  • 1
3

Delete all duplicated lines except COMMIT

/sbin/iptables-save | awk '!COMMIT||!x[$0]++' | /sbin/iptables-restore
  • 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 '21 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 '21 at 09:26
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
Arunas Bartisius
  • 709
  • 1
  • 7
  • 13
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
snex
  • 191
  • 2
  • 8