The task of blocking traffic from certain countries seems simple, but first impressions are deceiving. Today we will show you how this can be done.
prehistory
The results of a Google search on this topic are disappointing: most of the solutions have long been “rotten” and sometimes it seems that this topic has been shelved and forgotten about forever. We have gone through a lot of old records and are ready to share the modern version of the instructions.
We recommend that you read the entire article before executing these commands.
Operating system preparation
Filtering will be configured using the utility iptables, which requires an extension to work with GeoIP data. This extension can be found in
At the time of this writing, the current version of xtables-addons is 3.9. However, only 20.04 can be found in the default Ubuntu 3.8 LTS repositories, while 18.04 can be found in the Ubuntu 3.0 repositories. You can install the extension from the package manager with the following command:
apt install xtables-addons-common libtext-csv-xs-perl
Note that there are small but important differences between version 3.9 and the current state of the project, which we will discuss later. To build from source, install all the necessary packages:
apt install git build-essential autoconf make libtool iptables-dev libxtables-dev pkg-config libnet-cidr-lite-perl libtext-csv-xs-perl
Clone the repository:
git clone https://git.code.sf.net/p/xtables-addons/xtables-addons xtables-addons-xtables-addons
cd xtables-addons-xtables-addons
xtables-addons contains many extensions, but we are only interested in xt_geoip. If you do not want to drag unnecessary extensions into the system, you can exclude them from the assembly. To do this, you need to edit the file mconfig. For all desired modules put y, and mark all unnecessary n. We collect:
./autogen.sh
./configure
make
And install with superuser rights:
make install
During the installation of kernel modules, an error similar to the following may occur:
INSTALL /root/xtables-addons-xtables-addons/extensions/xt_geoip.ko
At main.c:160:
- SSL error:02001002:system library:fopen:No such file or directory: ../crypto/bio/bss_file.c:72
- SSL error:2006D080:BIO routines:BIO_new_file:no such file: ../crypto/bio/bss_file.c:79
sign-file: certs/signing_key.pem: No such file or directory
This situation arises due to the impossibility of signing kernel modules, because nothing to sign. You can solve this problem with a couple of commands:
cd /lib/modules/(uname -r)/build/certs
cat <<EOF > x509.genkey
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
CN = Modules
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
EOF
openssl req -new -nodes -utf8 -sha512 -days 36500 -batch -x509 -config x509.genkey -outform DER -out signing_key.x509 -keyout signing_key.pem
A compiled kernel module is installed, but the system does not detect it. Let's ask the system to create a dependency map given the new module, and then load it:
depmod -a
modprobe xt_geoip
Make sure xt_geoip is loaded into the system:
# lsmod | grep xt_geoip
xt_geoip 16384 0
x_tables 40960 2 xt_geoip,ip_tables
Additionally, make sure that the extension is loaded into iptables:
# cat /proc/net/ip_tables_matches
geoip
icmp
Everything suits us and it remains only to add the name of the module to / etc / modulesto make the module work after rebooting the OS. From now on, iptables understands geoip commands, but it doesn't have enough data to work with. Let's start loading the geoip database.
Getting the GeoIP database
Create a directory that will store information understandable to the iptables extension:
mkdir /usr/share/xt_geoip
At the beginning of the article, we mentioned that there are differences between the source code version and the package manager version. The most notable difference is the change in database provider and script xt_geoip_dl, which downloads the actual data.
Package manager version
The script is located along the /usr/lib/xtables-addons path, however, when you try to run it, you can see a not very informative error:
# ./xt_geoip_dl
unzip: cannot find or open GeoLite2-Country-CSV.zip, GeoLite2-Country-CSV.zip.zip or GeoLite2-Country-CSV.zip.ZIP.
Previously used as a database product GeoLite, now known as GeoLite Legacy, distributed under license
First, in January 2018
Secondly, from December 2019 MaxMind
Since we want to use their product, we will register on this page.
You will then receive an email asking you to set a password. Now that we have an account, we need to create a license key. In the personal account we find the item My License Keysand then click on the button Generate new License Key.
When creating a key, we will be asked only one question: will we use this key in the GeoIP Update program? We answer in the negative and press the button Confirm. The key will be displayed in a pop-up window. Save this key in a safe place, because after closing the pop-up window, you will no longer be able to see the full key.
We have the ability to download GeoLite2 bases manually, but their format is not compatible with the format expected by the xt_geoip_build script. This is where GeoLite2xtables scripts come to the rescue. For the scripts to work, install the NetAddr::IP perl module:
wget https://cpan.metacpan.org/authors/id/M/MI/MIKER/NetAddr-IP-4.079.tar.gz
tar xvf NetAddr-IP-4.079.tar.gz
cd NetAddr-IP-4.079
perl Makefile.PL
make
make install
Next, we clone the repository with scripts and write the previously obtained license key to the file:
git clone https://github.com/mschmitt/GeoLite2xtables.git
cd GeoLite2xtables
echo YOUR_LICENSE_KEY=’123ertyui123' > geolite2.license
Let's run the scripts:
# Скачиваем данные GeoLite2
./00_download_geolite2
# Скачиваем информацию о странах (для соответствия коду)
./10_download_countryinfo
# Конвертируем GeoLite2 базу в формат GeoLite Legacy
cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv |
./20_convert_geolite2 /tmp/CountryInfo.txt > /usr/share/xt_geoip/dbip-country-lite.csv
MaxMind imposes a limit of 2000 downloads per day and, with a large number of servers, offers to cache the update on a proxy server.
Note that the output file must be named dbip-country-lite.csv. Unfortunately, 20_convert_geolite2 produces not an ideal file. Script xt_geoip_build expects three columns:
- the beginning of the address range;
- end of address range;
- country code in iso-3166-alpha2.
And the output file contains six columns:
- start of address range (string representation);
- end of address range (string representation);
- beginning of the address range (numeric representation);
- end of address range (numeric representation);
- country code;
- the name of the country.
This discrepancy is critical and can be corrected in one of two ways:
- reign 20_convert_geolite2;
- reign xt_geoip_build.
In the first case, we reduce
/usr/lib/xtables-addons/xt_geoip_build -S /usr/share/xt_geoip/ -D /usr/share/xt_geoip
. . .
2239 IPv4 ranges for ZA
348 IPv6 ranges for ZA
56 IPv4 ranges for ZM
12 IPv6 ranges for ZM
56 IPv4 ranges for ZW
15 IPv6 ranges for ZW
Note that the author
Source version
When installing from source codes, scripts xt_geoip_* located in the directory /usr/local/libexec/xtables-addons. This version of the script uses a database
cd /usr/share/xt_geoip/
/usr/local/libexec/xtables-addons/xt_geoip_dl
/usr/local/libexec/xtables-addons/xt_geoip_build
After these steps, iptables is ready to go.
Using geoip in iptables
Module xt_geoip adds just two keys:
geoip match options:
[!] --src-cc, --source-country country[,country...]
Match packet coming from (one of) the specified country(ies)
[!] --dst-cc, --destination-country country[,country...]
Match packet going to (one of) the specified country(ies)
NOTE: The country is inputed by its ISO3166 code.
The way rules are generated for iptables is generally the same. To use keys from additional modules, you must explicitly specify the name of the module with the -m switch. For example, a rule to block incoming TCP connections on non-US port 443 on all interfaces:
iptables -I INPUT ! -i lo -p tcp --dport 443 -m geoip ! --src-cc US -j DROP
Files created by xt_geoip_build are used only when creating rules, but are not taken into account when filtering. Thus, to correctly update the geoip database, you must first update the iv* files, and then recreate all the rules that use geoip in iptables.
Conclusion
Packet filtering based on country affiliation is a somewhat forgotten strategy. Despite this, software tools for such filtering are being developed and, perhaps, a new version of xt_geoip with a new geoip data provider will soon appear in package managers, which will greatly simplify the life of system administrators.
Only registered users can participate in the survey.
Have you ever used country filtering?
-
59,1%Yes13
-
40,9%No9
22 users voted. 3 users abstained.
Source: habr.com