4

How I can read out IP addresses from file and then ban in iptables.

88.123.xxx
123.456.xxx
65.234.xxx

0

4 Answers 4

12

Simple, direct, one line solution:

for IP in $(cat ip_list); do iptables -A INPUT -s $IP/32 -d 0/0 -j DROP; done

This will block any communication from the ip addresses on any protocol or port.

But maybe you should think about doing a proper firewall script using iptables-save and iptables-restore or even Shorewall.

EDIT: The same line, verbose:

for IP in $(cat ip_list); do echo "Banning $IP"; iptables -A INPUT -s $IP/32 -d 0/0 -j DROP; done
9
  • It's worth learning to do this from memory. It's very useful to be able to create a loop whenever you want in bash.
    – Coops
    Feb 24, 2011 at 21:19
  • Very nice! Maybe it is possible to make verbose this line? I see nothing while it is working.
    – user66638
    Feb 24, 2011 at 21:26
  • And one last little question: it is possible to duplicate a line in iptables (for example: I add two same IP address)? If yes how I can remove duplicates from iptables?
    – user66638
    Feb 24, 2011 at 21:35
  • 1
    @coredump: $(cat ip_list | sort | uniq ) will remove dupes
    – user9517
    Feb 24, 2011 at 22:02
  • 1
    hm, it would be wise to do check what is output of iptables-save before applying this because with -A INPUT rules are appended at the end of input chain which leaves the possibility of ACCEPT rule allowing the traffic earlier on in the chain, so rather -I INPUT than -A INPUT in my opinion... Feb 24, 2011 at 23:30
3

Try this

#!/bin/bash
while read ipaddr
do
    /sbin/iptables -I INPUT -s $ipaddr -j DROP
done </path/to/iplist-to-drop | sort | uniq
~

Or using a separate chain

#!/bin/bash

/sbin/iptables -N Dropped-From-File
/sbin/iptables -I INPUT -s 0.0.0.0/0 -j Dropped-From-File
while read ipaddr
do

    /sbin/iptables -I Dropped-From-File -s $ipaddr -j DROP
done </path/to/iplist-to-drop | sort | uniq


/sbin/iptables -A Dropped-From-File -j RETURN
2

you could also use module ipset ( http://ipset.netfilter.org/ ). When list of ip addresses gets long, matching them one by one with individual iptables rules will lead to degraded performance. Ipset should perform much better. Also, with ipset you can reload addresses at any time without touching your rules.

Even if you dont want to bother with ipset, it is better to drop banned addresses in iptables "raw" table. This way, connection tracking framework will not see them and won't create state records you'll never need. This should also improve performance in case the firewall has to handle lots of traffic.

1

It is better to use ipset and table raw, as vadimk said. Here is how you do it

apt-get install ipset
ipset -N badips iphash
while read ip; do ipset -A badips "$ip"; done < badips.txt
iptables -t raw -I PREROUTING -m set --match-set badips src,dst -j DROP

To make this rules persistent on reboot on Debian 7 i had to use modified iptables-persistent

/etc/init.d/iptables-persistent save

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .