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:
#!/bin/bash COUNTRIES=('cn' 'ru' 'by') for COUNTRY in "${COUNTRIES[@]}"; do ipset create "countries_${COUNTRY}" hash:net done 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) do ipset add "countries_${i}" $IP done iptables -I blocked_countries -m set --match-set "countries_${i}" src -j LOGDROP -m comment --comment "Block .${i}" done
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 -- * * 0.0.0.0/0 0.0.0.0/0 match-set countries_by src /* Block .by */ 2182 155K LOGDROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set countries_ru src /* Block .ru */ 344 21370 LOGDROP all -- * * 0.0.0.0/0 0.0.0.0/0 match-set countries_cn src /* Block .cn */
Nice useful instructions. One thing I needed to do was create LOGDROP which I found steps here: https://blog.camilord.com/2010/07/15/iptables-logging-and-dropping-traffic-in-a-single-rule/
Thank you for the info.
that site seems to not have that file anymore, do you still have the instructions?
Missing IPv6 adresses, how to implement?
I think it should be LOG_DROP instead of LOGDROP