Monday, 23 December 2024

Block any country on your server's firewall with iptables or nftables

When we have a server exposed to the Internet, a fundamental recommendation is to configure your firewall to allow only the traffic that we want to allow, and deny the rest of the traffic. On many occasions we are victims of brute force attacks or denial of service attacks from countries other than Spain. In the vast majority of cases it is advisable to only allow the IP addresses of the country where you are, or your business is, and to deny by default any other traffic that we do not have on the allowed list. Today in RedesZone we are going to teach you to download all the IP ranges of a certain country to block it whenever we want, or to allow one of them, always using IPv4 since its use is majority if you are going to use IPv6 you will have to adapt the script.

Policies in a firewall: permissive or restrictive

Firewalls have mainly two policies, a permissive policy will allow all traffic except what we have specifically denied. In a restrictive policy, we will only allow traffic that we have specifically defined. For security, it is always advisable to have a restrictive policy on the Internet WAN, to avoid that a badly set rule can cause traffic that we do not want to enter our network, in addition, it is more efficient to have (few) rules to allow certain traffic and deny the rest in bulk than the other way around.

A very good policy in a firewall would be to allow only one or more countries, and deny the rest of the countries by default. Therefore, the script that we will present to you below can be easily modified to allow only the downloaded IP addresses or subnets, and later block the rest of the IP addresses by the policy.

Where do I get the IP addresses and ranges of the different countries?

In IPDeny you can find all the blocks of IPv4 addresses that belong to each country, in this way, we can obtain all the ranges of IP addresses in CIDR format of all the countries in the world, we will have the possibility to see the ranges of IPs in Spain, China, Russia and many others. The larger the country, the more ranges of IPv4 addresses we will have, so we will have to allow or deny access to those networks, to later ban or allow them. In this other link we have available the IPv6 address blocks of each country.

A very important detail is that IPDeny updates the entire IP address database very frequently, both IPv4 and IPv6, to prevent us from blocking IP addresses or ranges from one country that is actually in another. This web page is updated almost daily, as the IPv4 and IPv6 address blocks change or more are added.

Configuring iptables with ipset to block countries

iptables is the Linux firewall par excellence, although there are some distributions that are making the leap to nftables, which is the evolution of iptables, much faster, more efficient and easier to configure, however, currently we still use the iptables syntax although for below we are using nftables, as in the latest versions of the Debian operating system and many others. If you use iptables, it is highly recommended that you use the ipset extension, which will allow us to block or allow millions of IP addresses, but with higher performance than if we do it directly with IPtables. In the case of allowing or blocking an entire country, it is highly recommended to do it through ipset because it is clearly more efficient than iptables.

In order to use ipset with iptables, you need to install it because it is not installed by default, you can install it this way:

sudo apt install ipset

Once installed, we can start using it.

The following script that we have programmed consists of blocking a country or several, adding all its subnets downloaded from IPdeny and incorporating all the subnets to an ipset to later call that ipset and block it in iptables. This way, iptables will be much more efficient than if you do it without the ipset extension.

#!/bin/bash
# El objetivo de este script es BLOQUEAR todo el tráfico del pais que nosotros definamos, aunque tambien podriamos permitir solamente el nuestro, y denegar el resto.
# Autor: RedesZone.net; puedes compartir y modificar este script como desees.
# -------------------------------------------------------------------------------
#Elegiremos el nombre PAIS del pais que queremos BLOQUEAR
#Como ejemplo pondremos Andorra ya que tiene pocos rangos de direcciones IP.
PAIS="ad"
### Variables para facilitar el uso del script que apuntan a iptables (cortafuegos), ipset (extension de IPTABLESables), wget para coger los archivos de la base de datos y egrep para seleccionar la IP sin ningún símbolo que iptables no pueda interpretar ###
IPTABLES=/sbin/iptables
IPSET=/sbin/ipset
WGET=/usr/bin/wget
EGREP=/bin/egrep
#Ubicacion donde se guarda la base de datos de
BBDD="/root/iptables-bdd"
#URL de la base de datos de paises
URLDESCARGA="http://www.ipdeny.com/ipblocks/data/countries"
#Funcion para limpiar todas las reglas del firewall y lo ponemos por defecto.
limpiarReglasAntiguas(){
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F
$IPTABLES -t nat -X
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPSET flush paisbloqueado
$IPSET destroy paisbloqueado
}
#Creamos el directorio para almacenar la base de datos
[ ! -d $BBDD ] && /bin/mkdir -p $BBDD
#Ejecutamos la funcion
limpiarReglasAntiguas
for c in $PAIS
do
# Base de datos local
DBLOCAL=$BBDD/$c.zone
# Descargamos y actualizamos la base de datos
$WGET -O $DBLOCAL $URLDESCARGA/$c.zone
# Filtramos la base de datos para que IPTABLES interprete correctamente la base de datos y vamos anadiendo cada bloque de IP.
FILTROIPS=$(egrep -v "^#|^$" $DBLOCAL)
#Creamos el IPset nuevo para bloquear el pais
$IPSET create paisbloqueado hash:net
for ipbloqueo in $FILTROIPS
do
$IPSET add paisbloqueado $ipbloqueo
done
done
#Denegamos el tráfico del ipset creado.
$IPTABLES -I INPUT -m set --match-set paisbloqueado src -j DROP
#Permitimos todo el resto del trafico. CUIDADO CON ESTO
$IPTABLES -A INPUT -j ACCEPT
exit 0

Now we can see the status of iptables by putting the following, and we will see that it makes use of the configured ipset:

iptables -L

To see the status of the ipset, we put the following:

ipset list

Whenever we want to block a new country, you will have to run the script again and automatically all the ipset content will be deleted and all new subnets will be added from scratch. This is the most recommended because the different databases of IP addresses and ranges of the different countries are continually being updated. We must note that countries like China have a large number of IP address blocks, so it will take several minutes to apply all the rules to the firewall, if we try with only "ad" it is almost instantaneous because we have very few.

Thanks to this script, if our Internet service only works in Spain, we can ban all other countries, but we must bear in mind that if a user from Spain uses a proxy or VPN from another country, we will not allow access.

Configuration of iptables with ipset to allow Spain and block the rest

In this script we will do just the opposite of the previous one, what we will do is download the database of IP addresses of Spain, we will add it to the new ipset created and allow access. By default, what it will do is deny all other traffic from other countries. If your business is in Spain and you only want them to connect in Spain, this is the best and most efficient thing you can do because you will only be allowing one country and not specifically blocking the rest of the world.

#!/bin/bash
# El objetivo de este script es PERMITIR todo el tráfico del pais que nosotros definamos.
# Autor: RedesZone.net; puedes compartir y modificar este script como desees.
# -------------------------------------------------------------------------------
#Elegiremos el nombre PAIS del pais que queremos PERMITIR
#Como ejemplo pondremos Andorra ya que tiene pocos rangos de direcciones IP.
PAIS="ad"
### Variables para facilitar el uso del script que apuntan a iptables (cortafuegos), ipset (extension de IPTABLESables), wget para coger los archivos de la base de datos y egrep para seleccionar la IP sin ningún símbolo que iptables no pueda interpretar ###
IPTABLES=/sbin/iptables
IPSET=/sbin/ipset
WGET=/usr/bin/wget
EGREP=/bin/egrep
#Ubicacion donde se guarda la base de datos de
BBDD="/root/iptables-bdd"
#URL de la base de datos de paises
URLDESCARGA="http://www.ipdeny.com/ipblocks/data/countries"
#Funcion para limpiar todas las reglas del firewall y lo ponemos por defecto.
limpiarReglasAntiguas(){
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F
$IPTABLES -t nat -X
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPSET flush paispermitido
$IPSET destroy paispermitido
}
#Creamos el directorio para almacenar la base de datos
[ ! -d $BBDD ] && /bin/mkdir -p $BBDD
#Ejecutamos la funcion
limpiarReglasAntiguas
for c in $PAIS
do
# Base de datos local
DBLOCAL=$BBDD/$c.zone
# Descargamos y actualizamos la base de datos
$WGET -O $DBLOCAL $URLDESCARGA/$c.zone
# Filtramos la base de datos para que IPTABLES interprete correctamente la base de datos y vamos anadiendo cada bloque de IP.
FILTROIPS=$(egrep -v "^#|^$" $DBLOCAL)
#Creamos el IPset nuevo para bloquear el pais
$IPSET create paispermitido hash:net
for ippermitir in $FILTROIPS
do
$IPSET add paispermitido $ippermitir
done
done
#Permitimos el tráfico del ipset creado.
$IPTABLES -I INPUT -m set --match-set paispermitido src -j ACCEPT
#DENEGAMOS todo el resto del trafico.
$IPTABLES -A INPUT -j DROP
exit 0

Now we can see the status of iptables by putting the following, and we will see that it makes use of the configured ipset:

iptables -L

To see the status of the ipset, we put the following:

ipset list

As you have seen, it is really easy to block or allow a country using ipset from iptables, in addition, it is much more efficient than doing it directly with iptables, so we recommend that you always use ipset for this kind of actions.

Nftables configuration to block countries

nftables is the new Linux firewall, better, faster and more intuitive than the popular iptables that we have always used. nftables is already installed in most Linux distributions even if we use iptables syntax. If you use the latest versions of Debian, you will already be using nftables without knowing it, but we will not be able to use the syntax of nftables itself.

To be able to use nftables 100%, we will have to install it directly from the repositories, executing the following command:

sudo apt install nftables

Once installed, we can start configuring nftables with the "nft" command. The syntax is radically different from iptables, so if you haven't used it, it will take a while to adjust to the new syntax.

The following script that we have programmed consists of blocking a country or several, adding all its subnets downloaded from IPdeny and incorporating all subnets to nftables to block it in the firewall. We must remember that nftables are much more efficient than iptables, and it will work really well.

#!/bin/bash
# El objetivo de este script es BLOQUEAR todo el tráfico del pais que nosotros definamos, aunque tambien podriamos permitir solamente el nuestro, y denegar el resto.
# Autor: RedesZone.net; puedes compartir y modificar este script como desees.
# -------------------------------------------------------------------------------
#Elegiremos el nombre PAIS del pais que queremos BLOQUEAR
#Como ejemplo pondremos Andorra ya que tiene pocos rangos de direcciones IP.
PAIS="ad"
### Variables para facilitar el uso del script que apuntan a nftables (cortafuegos), wget para coger los archivos de la base de datos y egrep para seleccionar la IP sin ningún símbolo que NFT no pueda interpretar ###
NFT=/sbin/nft
WGET=/usr/bin/wget
EGREP=/bin/egrep
#Ubicacion donde se guarda la base de datos de
BBDD="/root/NFT-bdd"
#URL de la base de datos de paises
URLDESCARGA="http://www.ipdeny.com/ipblocks/data/countries"
#Funcion para limpiar todas las reglas del firewall y lo ponemos por defecto.
limpiarReglasAntiguas(){
$NFT flush set filter ips_baneadas
$NFT flush chain ip filter INPUT
}
#Creamos el directorio para almacenar la base de datos
[ ! -d $BBDD ] && /bin/mkdir -p $BBDD
#Ejecutamos la funcion
limpiarReglasAntiguas
for c in $PAIS
do
# Base de datos local
DBLOCAL=$BBDD/$c.zone
# Descargamos y actualizamos la base de datos
$WGET -O $DBLOCAL $URLDESCARGA/$c.zone
# Filtramos la base de datos para que NFT interprete correctamente la base de datos y vamos anadiendo cada bloque de IP.
FILTROIPS=$(egrep -v "^#|^$" $DBLOCAL)
#Creamos el set de ips_baneadas de tipo IPv4.
$NFT add set ip filter ips_baneadas {type ipv4_addr; flags interval;}
#Metemos en el set todos los rangos de IP.
for ipbloqueo in $FILTROIPS
do
$NFT add element ip filter ips_baneadas { $ipbloqueo }
done
done
#Bloqueamos todo lo que coincida con el SET anteriormente creado.
$NFT add rule ip filter INPUT ip saddr @ips_baneadas counter drop
$NFT list ruleset > /etc/nftables.conf
systemctl restart nftables.service
exit 0

Now we can see the state of nftables by putting the following, and we will see that it makes use of the configured ipset:

nft list ruleset

Nftables configuration to allow countries

The next script that we have programmed consists of allowing a country, adding all its subnets downloaded from IPdeny and incorporating all the subnets to nftables to allow it in the firewall, the rest of the traffic will be denied. We must remember that nftables is much more efficient than iptables, and it will work really well.

#!/bin/bash
# El objetivo de este script es PERMITIR todo el tráfico del pais que nosotros definamos, aunque tambien podriamos permitir solamente el nuestro, y denegar el resto.
# Autor: RedesZone.net; puedes compartir y modificar este script como desees.
# -------------------------------------------------------------------------------
#Elegiremos el nombre PAIS del pais que queremos PERMITIR
#Como ejemplo pondremos Andorra ya que tiene pocos rangos de direcciones IP.
PAIS="ad"
### Variables para facilitar el uso del script que apuntan a nftables (cortafuegos), wget para coger los archivos de la base de datos y egrep para seleccionar la IP sin ningún símbolo que NFT no pueda interpretar ###
NFT=/sbin/nft
WGET=/usr/bin/wget
EGREP=/bin/egrep
#Ubicacion donde se guarda la base de datos de
BBDD="/root/NFT-bdd"
#URL de la base de datos de paises
URLDESCARGA="http://www.ipdeny.com/ipblocks/data/countries"
#Funcion para limpiar todas las reglas del firewall y lo ponemos por defecto.
limpiarReglasAntiguas(){
$NFT flush set filter ips_permitidas
$NFT flush chain ip filter INPUT
}
#Creamos el directorio para almacenar la base de datos
[ ! -d $BBDD ] && /bin/mkdir -p $BBDD
#Ejecutamos la funcion
limpiarReglasAntiguas
for c in $PAIS
do
# Base de datos local
DBLOCAL=$BBDD/$c.zone
# Descargamos y actualizamos la base de datos
$WGET -O $DBLOCAL $URLDESCARGA/$c.zone
# Filtramos la base de datos para que NFT interprete correctamente la base de datos y vamos anadiendo cada bloque de IP.
FILTROIPS=$(egrep -v "^#|^$" $DBLOCAL)
#Creamos el set de ips_permitidas de tipo IPv4.
$NFT add set ip filter ips_permitidas {type ipv4_addr; flags interval;}
#Metemos en el set todos los rangos de IP.
for ippermitida in $FILTROIPS
do
$NFT add element ip filter ips_permitidas { $ippermitida }
done
done
#Permitimos todo lo que coincida con el SET anteriormente creado.
$NFT add rule ip filter INPUT ip saddr @ips_permitidas counter accept
#Bloqueamos todo lo demas en cadena base
$NFT add chain ip filter INPUT '{ policy drop; }'
#Guardamos y reiniciamos servicio
$NFT list ruleset > /etc/nftables.conf
systemctl restart nftables.service
exit 0

Now we can see the state of nftables by putting the following, and we will see that it makes use of the configured ipset:

nft list ruleset

So far we have come with this tutorial on iptables and ipset to block or allow IPs from different countries, we have also seen how to do it with nftables, the new Linux firewall with a new syntax that is much more intuitive, but that will cost us some work get used to it if we have always worked with iptables.

 

Link: https://www.redeszone.net/tutoriales/seguridad/bloquear-ip-paises-firewall-iptables-nftables/

NOC-RD, is part of NOCPERU. We consider as an important factor that your company or organization received all the facilities to achieve the objetives they seek

Contact Us

Trujillo, La Libertad, Perú
01 641 1239
044 64 3108
01 305-749-5753
+51 902 524 298

Social Link