4

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

88.123.xxx
123.456.xxx
65.234.xxx

9

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
  • 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 '11 at 21:19
  • Very nice! Maybe it is possible to make verbose this line? I see nothing while it is working. – user66638 Feb 24 '11 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 '11 at 21:35
  • 1
    @coredump: $(cat ip_list | sort | uniq ) will remove dupes – Iain Feb 24 '11 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... – Hrvoje Špoljar Feb 24 '11 at 23:30
2

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

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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