Block a whole country with netfilter

Block a whole country with netfilter

In recent times, port probes, spam mail and also SIP attacks / SIP fraud have increased massively and it mostly comes from China, Korea and Palestine. If you run Linux as perimeter firewall, blocking those 3 (and any other you like) is fairly easy. This script downloads the respective network lists from ipdeny.com and inserts rules at the start of the INPUT and FORWARD chains, so IPs from any of those networks can neither reach your firewall not any system behind it.

NOTE: This script is for a firewall host, i.e. a host that sits between the internet and a local network. For usage on hosts which do not route packages, you can/should remove the inserting of packes into the FORWARD chain.

NOTE2: 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

IPTABLES="/sbin/iptables"
any="0.0.0.0/0"
BLOCKDIR="blocklist.d"

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


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

    code=$(echo ${FILE} | cut -d/ -f2 | cut -d. -f1 | tr [:lower:] [:upper:])

    echo "Flushing blocklist table for ${code}..."
    if ! iptables -X BLOCK-${code}; then
        echo "Blocklist table for ${code} not found, creating..."
        $IPTABLES -N BLOCK-${code}
        $IPTABLES -A BLOCK-${code} -s $any -d $any -j LOG --log-prefix "Packet log: BLOCK-${code} DROP "
        $IPTABLES -A BLOCK-${code} -s $any -d $any -j DROP
    fi

    echo -n "Inserting rules for ${code} "
    for ADDRESS in $(cat ${FILE}); do
        echo -n "."
        $IPTABLES -I INPUT -s ${ADDRESS} -d $any -j BLOCK-${code}
        $IPTABLES -I FORWARD -s ${ADDRESS} -d $any -j BLOCK-${code}
    done
    echo ""
done

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