Skip to main content

Block a whole country with a Cisco ASA

Submitted by Stefan Gofferje on Tue, 10/07/2014 - 22:20

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)"