iptables country block
This tool will automatically create iptables rules on Linux system to block all connection from one country or more. The blocklist is created with an API that fetch data in our SQL database based on IP address country location.
Data accuracy
The list of IP address by country below is a grouping of IP by country and CIDR of our database. The data has over 99.5% accuracy on a country basis.
API Usage
First you need to know the code (ISO 3166 format) of the country you would like to block. The full list is available here. Once you have the country code, you can now get the list at the following url (Afghanistan and Argentina in this example). If your browser show the data on a single line, simply view the page source code :http://ipinfodb.com/country_query.php?country=AF,AR
58.147.128.0/19
67.212.160.0/24
80.247.139.0/24
82.205.190.0/21
82.205.198.0/23
82.205.202.0/22
[...]
Automatic bash script
The following script will fetch the right IP addresses of the country you would like to block from our API and then add these rules in iptables.#!/bin/bash ### IpInfoDB iptables countries block bash script### ### Slightly modified script from http://www.cyberciti.biz ### Countries code available : http://ipinfodb.com/country.txt ### ### 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 ZONEROOT="/root/iptables/" IPTCBRESTORE="/root/iptables/iptables.cb" ### Network config ### IPTCBDEVICE=eth0 ALLOWPORTS=80,443 ALLOWSUBNET=192.168.0.0/255.255.0.0 ### No editing below ### CBLIST="countrydrop" MAXZONEAGE=7 DLROOT="http://ipinfodb.com/country_query.php?country=" cleanOldRules(){ $IPT -L $CBLIST > /dev/null 2>&1 if [ $? = 0 ] ; then $IPT -D INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST $IPT -D OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST $IPT -D FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST fi $IPT -F $CBLIST $IPT -X $CBLIST for i in `$IPT -L -n | grep Chain | cut -f 2 -d ' ' | grep '\-$CBLIST'` do $IPT -F ${i} $IPT -X ${i} done } updateZoneFiles() { ZONEARCH=${ZONEROOT}/arch mkdir -p ${ZONEARCH} find ${ZONEROOT} -maxdepth 1 -mindepth 1 -ctime +${MAXZONEAGE} -exec mv {} ${ZONEARCH} \; for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone if [ -f $tDB ] ; then printf "Zone file %s is new enough - no update required.\n" $tDB else # get fresh zone file if it is newer than MAXZONEAGE days $WGET -O $tDB $DLROOT$c fi done oldzones=`find ${ZONEROOT} -mindepth 1 -maxdepth 1 -type f -exec basename {} \; | cut -f 1 -d '.'` # Archive old zones no longer blocked for z in $oldzones ; do archme=${c} for c in $ISO ; do if [ $c = $z ] ; then archme="X"; fi done if [ $archme = $z ] ; then mv ${archme} ${ZONEARCH} else printf "Working from previous zone file for %s\n" ${z} fi done } createIPTLoadFile() { printf "# Generated by %s on" $0 > ${IPTCBRESTORE} printf "%s " `date` >> ${IPTCBRESTORE} printf "\n*filter\n" >> ${IPTCBRESTORE} # Create CBLIST chain printf ":$CBLIST - [0:0]\n" >> ${IPTCBRESTORE} printf "%s INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" > ${IPTCBRESTORE}.tmp printf "%s OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST\n" "-I" >> ${IPTCBRESTORE}.tmp printf "%s FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" >> ${IPTCBRESTORE}.tmp if [ "Z${ALLOWPORTS}" = "Z" ] ; then printf "Blocking all traffic from country - no ports allowed\n" else printf "%s $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j RETURN\n" "-I">> ${IPTCBRESTORE}.tmp fi if [ "Z${ALLOWSUBNET}" = "Z" ] ; then printf "Blocking all traffic from country - no subnets excluded\n" else printf "%s $CBLIST -s ${ALLOWSUBNET} -j RETURN\n" "-I">> ${IPTCBRESTORE}.tmp fi for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone # country specific log message SPAMDROPMSG="iptables: ${c}-Country-Drop: " # Create drop chain for identified packets CBLISTDROP=${c}-${CBLIST}-DROP printf ":${CBLISTDROP} - [0:0]\n" >> ${IPTCBRESTORE} printf "%s ${CBLISTDROP} -j LOG --log-prefix \"$SPAMDROPMSG\"\n" "-A" >> ${IPTCBRESTORE}.tmp printf "%s ${CBLISTDROP} -j DROP\n" "-A" >> ${IPTCBRESTORE}.tmp # Load IP ranges into chains correlating to first octet BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do topip=`echo $ipblock | cut -f 1 -d '.'` chainExists=`grep -c :${topip}-${CBLIST} ${IPTCBRESTORE}` if [ $chainExists = 0 ] ; then printf "Creating chain for octet %s\n" ${topip} printf ":$topip-$CBLIST - [0:0]\n" >> ${IPTCBRESTORE} sip=${topip}.0.0.0/8 printf "%s $CBLIST -s ${sip} -j $topip-$CBLIST\n" "-A" >> ${IPTCBRESTORE}.tmp fi printf " Adding rule for %s to chain for octet %s\n" ${ipblock} ${topip} printf "%s $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}\n" "-A" >> ${IPTCBRESTORE}.tmp done done cat ${IPTCBRESTORE}.tmp >> ${IPTCBRESTORE} && rm -f ${IPTCBRESTORE}.tmp printf "COMMIT\n# Completed on " >> ${IPTCBRESTORE} printf "%s " `date` >> ${IPTCBRESTORE} printf "\n" >> ${IPTCBRESTORE} } directLoadTables() { # Create CBLIST chain $IPT -N $CBLIST $IPT -I INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST $IPT -I OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST $IPT -I FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST if [ "Z${ALLOWPORTS}" = "Z" ] ; then printf "Blocking all traffic from country - no ports allowed\n" else $IPT -I $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j RETURN fi if [ "Z${ALLOWSUBNET}" = "Z" ] ; then printf "Blocking all traffic from country - no subnets allowed\n" else $IPT -I $CBLIST -s ${ALLOWSUBNET} -j RETURN fi for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone # country specific log message SPAMDROPMSG="$c Country Drop" # Create drop chain for identified packets CBLISTDROP=${c}-${CBLIST}-DROP $IPT -N ${CBLISTDROP} $IPT -A ${CBLISTDROP} -j LOG --log-prefix "$SPAMDROPMSG" $IPT -A ${CBLISTDROP} -j DROP # Load IP ranges into chains correlating to first octet BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do topip=`echo $ipblock | cut -f 1 -d '.'` $IPT -L $topip-$CBLIST > /dev/null 2>&1 if [ $? = 1 ] ; then printf "Creating chain for octet %s\n" ${topip} $IPT -N $topip-$CBLIST sip=${topip}.0.0.0/8 $IPT -A $CBLIST -s ${sip} -j $topip-$CBLIST fi printf " Adding rule for %s to chain for octet %s\n" ${ipblock} ${topip} $IPT -A $topip-$CBLIST -s $ipblock -j ${CBLISTDROP} done done } loadTables() { createIPTLoadFile ${IPT}-restore -n ${IPTCBRESTORE} #directLoadTables printf "Country block instituted for: %s\n" "$ISO" } # create a dir [ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT # clean old rules cleanOldRules # update zone files as needed updateZoneFiles # create a new iptables list loadTables exit 0
