May 6, 2024

The mountain of shit theory

Uriel Fanelli's blog in English

Fediverse

How to block russian / Belarusian IPs on Linux

We are living strange days. This is why I'm asked how to use iptables to block any source IP coming from Russia and Belarus. I guess the idea is to help the Russian and Belarusian Authorities to blacklist bad contents, so take it as an act of love for the Roskomnadzor. Of course, people using a VPN will keep reaching you.

The first point is that to use the GEOIP together with iptables is kind of a shit of job. It would imply to query a file while the network is running, whatever source IP you have; maybe the IP is russian, maybe don't, and you still add latency. Not good.

But, we have alternatives.

First, Russian and Bielorussian IPs are assigned by the RIPE.

Second, the RIPE keeps a registry of assigned IP blocks in a text file, which you can download from here:

ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-latest

The small issue is, instead of using CIDR they are using the block size, like:

 ripencc|UA|ipv4|2.56.168.0|256|20200430|allocated ripencc|CH|ipv4|2.56.169.0|256|20200430|allocated ripencc|DE|ipv4|2.56.170.0|256|20200430|allocated ripencc|BE|ipv4|2.56.171.0|256|20200430|allocated ripencc|CY|ipv4|2.56.172.0|1024|20190314|allocated ripencc|CY|ipv4|2.56.176.0|1024|20190314|allocated ripencc|RU|ipv4|2.56.180.0|1024|20190314|allocated ripencc|LT|ipv4|2.56.184.0|1024|20190315|allocated ripencc|GB|ipv4|2.56.188.0|1024|20190315|allocated ripencc|NL|ipv4|2.56.192.0|1024|20190315|allocated ripencc|GB|ipv4|2.56.196.0|1024|20190315|allocated ripencc|NL|ipv4|2.56.200.0|1024|20190315|allocated ripencc|AM|ipv4|2.56.204.0|1024|20190315|allocated ripencc|AT|ipv4|2.56.208.0|1024|20190315|allocated ripencc|CY|ipv4|2.56.212.0|1024|20190315|allocated ripencc|NL|ipv4|2.56.216.0|1024|20190315|allocated ripencc|LU|ipv4|2.56.220.0|1024|20190315|allocated ripencc|NL|ipv4|2.56.224.0|1024|20190315|allocated ripencc|US|ipv4|2.56.228.0|1024|20190315|allocated ripencc|MD|ipv4|2.56.232.0|1024|20190315|allocated ripencc|DE|ipv4|2.56.236.0|1024|20190315|allocated ripencc|RU|ipv4|2.56.240.0|1024|20190315|allocated ripencc|DE|ipv4|2.56.244.0|1024|20190315|allocated ripencc|LT|ipv4|2.56.248.0|1024|20190315|allocated ripencc|DE|ipv4|2.56.252.0|512|20190315|allocated ripencc|DE|ipv4|2.56.254.0|256|20190315|allocated ripencc|IN|ipv4|2.56.255.0|256|20190315|allocated ripencc|FI|ipv4|2.57.0.0|1024|20190315|allocated

So we need to convert the blocksize to a CIDR.

And then? Then we can select the records with “RU” and “BY”, and add to an IPset.

How we do it?

With Python. Why? Because Python uses indentation as grammar, so that your capability to troubleshoot will depend by the size of your monitor / terminal. Brilliant design, isn't it?

So, how we do it with Python? Easy:

 #!/usr/bin/python import os import math import urllib opener = urllib.FancyURLopener() f = opener.open("ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-latest") lines=f.readlines() os.system('ipset create rusbiel nethash') os.system('iptables -A INPUT -m set --match-set rusbiel src -j LOG') os.system('iptables -A INPUT -m set --match-set rusbiel src -j DROP') os.system('ipset flush rusbiel') for line in lines: if (('ipv4' in line) & (('RU' in line) or ('BY' in line)) ) : s=line.split("|") net=s[3] cidr=float(s[4]) final_cidr= (str(net) + "/" + str( math.trunc((32-math.log(cidr,2))) )) ipset_cmd="ipset -q -A rusbiel " + final_cidr os.system(ipset_cmd) print(ipset_cmd)

Very brutal but efficient code. So brutal, it could be russian.

After doing this, everything you need is to run the script every night with cron, and suddenly only people using a VPN will be able to reach your server from Russia and Belarus, thus helping the Roskomnadzor to keep russian nationalist out of your website.

Smart (bielo) russians using a VPN or TOR will be able to read it.

Have fun!

Leave a Reply

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