Home –  How to – How to block a country using iptables?

How to block a country using iptables?

If you are an admin of a website and you see a lot of bogus traffic coming from some countries which give no profit to you, and you want to block those countries from accessing your website then you can use the bash script given below.

There are two ways to block countries. First is to configure your Apache server and second is to set iptables commands. We will do this using iptables. First of all download the list of IP zone files of the country which you want to block from here.

The script will not work if people of that country are using any proxy server or they have spoofed their IP address.

#!/bin/bash
### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ###
ISO="af cn"
 
### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep
 
### No editing below ###
SPAMLIST="countrydrop"
ZONEROOT="/root/iptables"
DLROOT="http://www.ipdeny.com/ipblocks/data/countries"
 
cleanOldRules(){
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
}
 
# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT
 
# clean old rules
cleanOldRules
 
# create a new iptables list
$IPT -N $SPAMLIST
 
for c  in $ISO
do
	# local zone file
	tDB=$ZONEROOT/$c.zone
 
	# get fresh zone file
	$WGET -O $tDB $DLROOT/$c.zone
 
	# country specific log message
	SPAMDROPMSG="$c Country Drop"
 
	# get
	BADIPS=$(egrep -v "^#|^$" $tDB)
	for ipblock in $BADIPS
	do
	   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
	   $IPT -A $SPAMLIST -s $ipblock -j DROP
	done
done
 
# Drop everything
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
 
# call your other iptable script
# /path/to/other/iptables.sh
 
exit 0

You must be logged in as a ‘root’ user to run this script. Mention the country names which you want to block in ‘ISO’.

To run the script

# /path/block_country.sh

You can add this script to crontab so that it will run automatically.

@weekly /path/block_country.sh

Below is an another script which does the same work:

#!/bin/bash
###PUT HERE COMA SEPARATED LIST OF COUNTRY CODE###
COUNTRIES="AK,AR"
WORKDIR="/root"
#######################################
cd $WORKDIR
wget -c --output-document=iptables-blocklist.txt http://blogama.org/country_query.php?country=$COUNTRIES
if [ -f iptables-blocklist.txt ]; then
  iptables -F
  BLOCKDB="iptables-blocklist.txt"
  IPS=$(grep -Ev "^#" $BLOCKDB)
  for i in $IPS
  do
    iptables -A INPUT -s $i -j DROP
    iptables -A OUTPUT -d $i -j DROP
  done
fi
rm $WORKDIR/iptables-blocklist.txt

16 thoughts on “How to block a country using iptables?

  1. Anonymous

    What will a blocked user see when they visit the website using this method?

  2. seth

    Unfortunately you’re limited to ~200 rules before you really start slowing network traffic using iptables (every packet needs to be checked for every rule in sequence until a match is found).

    Someone needs to write some software that tracks when you’re being attacked and then temporarily adds an iptables rule that times out in some period of time (maybe it already exists).

  3. phpguy

    Good job. IP tables dont look that scary a lot of sys admins try to make it sound like vodoo.

  4. haris

    @seth: check OpenBSD’s pf for this.

  5. turrini

    I suggest using ipset with iptables instead. You can insert thousand of addresses without any noticeable perfomance hit.

  6. Iptables is not as much used now to do so … as prefered on dedicated firewall to achieve so ..

    Nice article Chankey..used script.good keep it up ..

    • turrini

      Sorry, but I have to disagree…

      First, firewall appliances (eg. sonicwall, juniper) internally uses linux with netfilter (userspace -> iptables, smoothwall, etc.), so basically it’s the same thing.

      Second, if one needs speed to import thousands of addresses to netfilter, one can use ipset with/or iptables-restore to read a previously saved configuration much more quickier than using a bash script.

      • shirish

        Dear turrini!
        First: firewalling with firewall and same with iptables have much diff… am not aure about on what basic you are comparing so.. check cost and specification/capability on google. .
        Second: The script above is nothing but what we can do manual 200 cmnds steps ..so it’s good ..

  7. amin

    good job….for making the internet a worst place.
    there are legit people living in those countries. but whatever. let’s block the whole IP range…

  8. Nigel

    Well amin all those people in those countries are NOT supposed to be trying to hack my Asterisk. No-one from anywhere except US and UK is invited to be hanging off my system so I feel very justified blocking entire countries.

    • Pops

      Sorry Amin, but I agree with Nigel. Most businesses will not block a country’s IP space, but most SOHO and residences should. There’s no reason for a peer in my own country to be scanning my SOHO premise router or firewall, let alone someone from a foreign country. No reason at all. Why would this be a dis-service to the people in ANY country?

  9. Dennis

    Your second script is nice, short, and simple but… the web-site’s list of IP addresses does not exist. In other words there is nothing to wget from http://blogama… etc.

  10. Patrick

    i added the code but they can still connect :l

Leave a Reply

Your email address will not be published. Required fields are marked *