Block countries using IPtables and IPDeny.com


Certain server setups do not require access for all countries or just want to block certain countries since they are know for their malicious activity.

One simple (not full bullet-proof) way of doing this, is by setting up block rules on firewall level, which can be achieved on Linux servers with iptables and zone files of https://www.ipdeny.com/. These zone files contain the network ranges assigned to a specific country.

The network ranges are fed to a tool called ipset, which sets up of hash map that can be easily used within iptables rules.

On Debian/Ubuntu systems, ipset can be installed with the apt command:

apt install ipset

Next, create an iptables chain called “blocked_countries“, to which we will add rules afterwards. Add this chain to the beginning of the INPUT and FORWARD chain, to have early blocking in your ruleset.

iptables -N blocked_countries
iptables -I INPUT -j blocked_countries -m comment --comment "Blocked countries"
iptables -I FORWARD -j blocked_countries -m comment --comment "Blocked countries"

Finally, create a shell script which will download the required zone files from https://ipdeny.com/ and which feeds them to ipset. The example script will try to block the countries China, Russia and Belarus:


COUNTRIES=('cn' 'ru' 'by')

for COUNTRY in "${COUNTRIES[@]}"; do
    ipset create "countries_${COUNTRY}" hash:net

iptables -v -F blocked_countries

for i in "${COUNTRIES[@]}"; do
    echo "Ban IP of country ${i}"
    ipset flush "countries_${i}"

    for IP in $(wget -O - https://www.ipdeny.com/ipblocks/data/countries/${i}.zone)
        ipset add "countries_${i}" $IP
    iptables -I blocked_countries   -m set --match-set "countries_${i}" src  -j LOGDROP -m comment   --comment "Block .${i}"

You can check the blocked_countries chain if packets are being blocked by your new rules:

iptables -v -n -L blocked_countries 
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain blocked_countries (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    2   104 LOGDROP    all  --  *      *              match-set countries_by src /* Block .by */
 2182  155K LOGDROP    all  --  *      *              match-set countries_ru src /* Block .ru */
  344 21370 LOGDROP    all  --  *      *              match-set countries_cn src /* Block .cn */

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Previous Post

Install OpenBSD 6.0 on a Soekris net6501

Next Post

Block countries on OpenBSD using pf

Related Posts