Block a whole country with a Cisco ASA

Block a whole country with a Cisco ASA

Thanks to some good pointers from Vibhor Amrodia here, I was able to rewrite my Linux Netfilter countryblock script to create object-groups for Cisco ASA firewalls which can easily be used in access-lists. This example loads the IP-ranges of China, Korea and Palestine from ipdeny.com and creates a config file. This config file can easily be copied from a TFTP server to the running config of the ASA. I chose those 3 countries because the vast majority of probes, scans and SIP fraud attempts on my network come from there.

NOTE: ipdeny.com has recently been a bit lame with updating their lists but they are still a good source - not alone because their lists are easy to parse in scripts.

Disclaimer: This script comes with no guarantee nor support! I don’t assume any kind of liability! If you don’t know what you are doing, you shouldn’t build a firewall yourself.

#!/bin/bash

WORKDIR="/storage/tftp"               # Put your TFTP directory here
BLOCKDIR="${WORKDIR}/blocklist.d"
BLOCKFILE="${WORKDIR}/blocklist.asa"

function cdr2mask
{
     # Number of args to shift, 255..255, first non-255 byte, zeroes
     set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
     [ $1 -gt 1 ] && shift $1 || shift
     echo ${1-0}.${2-0}.${3-0}.${4-0}
}

if ! test -d ${BLOCKDIR}; then
     mkdir ${BLOCKDIR}
fi

DATE=$(date)

echo "Country blocking rules..."
echo "Downloading rules..."

curl -s http://www.ipdeny.com/ipblocks/data/countries/cn.zone -o ${BLOCKDIR}/cn.zone 
     || echo "Warning: Couldn't download CN zone"

curl -s http://www.ipdeny.com/ipblocks/data/countries/kr.zone -o ${BLOCKDIR}/kr.zone 
     || echo "Warning: Couldn't download KR zone"

curl -s http://www.ipdeny.com/ipblocks/data/countries/ps.zone -o ${BLOCKDIR}/ps.zone 
     || echo "Warning: Couldn't download PS zone"

echo "Done downloading."

echo "! Country objects - $(date)" > ${BLOCKFILE}

for FILE in ${BLOCKDIR}/*.zone; do

     CODE=$(basename ${FILE} | cut -d. -f1 | tr [:lower:] [:upper:])

     echo "! --- ${CODE} ---------------------------------------------------------------" >> ${BLOCKFILE}
     echo "no object-group network block-${CODE}" >> ${BLOCKFILE}
     echo "object-group network block-${CODE}" >> ${BLOCKFILE}
     
     for ADDRESS in $(cat ${FILE}); do
          ADR=$(echo ${ADDRESS} | cut -d/ -f1)
          SUN=$(echo ${ADDRESS} | cut -d/ -f2)
          MSK=$(cdr2mask ${SUN})
          echo -n "."
          echo "network-object ${ADR} ${MSK}" >> ${BLOCKFILE}
     done
     echo ""
done

echo "Done. Started: ${DATE}, finished: $(date)"