Cuando tenemos un servidor expuesto a Internet, una recomendación fundamental es configurar su firewall para permitir solamente el tráfico que nosotros queremos permitir, y denegar el resto del tráfico. En muchas ocasiones somos víctimas de ataques de fuerza bruta o ataques de denegación de servicio de otros países que no es España. En la gran mayoría de ocasiones es recomendable permitir solamente las direcciones IP del país donde tú estés, o esté tu negocio, y denegar por defecto cualquier otro tráfico que no tengamos en la lista de permitidos. Hoy en RedesZone os vamos a enseñar a descargar todos los rangos de IP de un determinado país para bloquearlo siempre que nosotros queramos, o para permitir uno de ellos, siempre haciendo uso de IPv4 ya que su uso es mayoritario, si vas a usar IPv6 tendrás que adaptar el script.
Políticas en un firewall: permisiva o restrictiva
Los firewalls tienen principalmente dos políticas, una política permisiva permitirá todo el tráfico excepto el que tengamos específicamente denegado. En una política restrictiva, solamente tendremos permitido el tráfico que hemos definido específicamente. Por seguridad, siempre es recomendable tener una política restrictiva en la WAN de Internet, para evitar que una regla mal puesta pueda hacer que entre un tráfico que no queramos en nuestra red, además, es más eficiente tener (pocas) reglas para permitir cierto tráfico y denegar el resto de forma masiva que al revés.
Una muy buena política en un firewall sería permitir solamente uno o varios países, y denegar el resto de países por defecto. Por tanto, el script que os presentaremos a continuación podremos modificarlo fácilmente para permitir solamente las direcciones IP o subredes descargadas, y posteriormente bloquear el resto de direcciones IP por política.
¿Dónde consigo las direcciones IP y rangos de los diferentes países?
En IPDeny podéis encontrar todos los bloques de direcciones IPv4 que pertenecen a cada país, de esta forma, podremos obtener todos los rangos de direcciones IP en formato CIDR de todos los países del mundo, tendremos la posibilidad de ver los rangos de IPs de España, China, Rusia y muchos otros. Cuanto más grande es el país, más rangos de direcciones IPv4 tendremos, por lo que tendremos que permitir o denegar el acceso de esas redes, para posteriormente banearlas o permitirlas. En este otro enlace tenemos disponibles los bloques de direcciones IPv6 de cada país.
Un detalle muy importante es que IPDeny actualiza con mucha frecuencia toda la base de datos de direcciones IP, tanto de IPv4 como de IPv6, para evitar que estemos bloqueando direcciones IP o rangos de un país que realmente está en otro. Esta página web se va actualizando casi diariamente, a medida que los bloques de direcciones IPv4 y IPv6 van cambiando o se van incorporando más.
Configuración de iptables con ipset para bloquear países
iptables es el firewall de Linux por excelencia, aunque hay algunas distribuciones que están dando el salto a nftables que es la evolución de iptables, mucho más rápido, eficiente y fácil de configurar, sin embargo, actualmente aún seguimos utilizando al sintaxis de iptables aunque por debajo estemos usando nftables, como ocurre en las últimas versiones del sistema operativo Debian y muchos otros. Si haces uso de iptables, es muy recomendables que utilices la extensión ipset, que nos permitirá bloquear o permitir millones de direcciones IP, pero con un mayor rendimiento que si lo hacemos directamente con IPtables. En el caso de permitir o bloquear un país entero, es muy recomendable hacerlo a través de ipset porque es claramente más eficiente que iptables.
Para poder hacer uso de ipset con iptables, es necesario que lo instales porque no viene instalado de manera predeterminada, puedes instalarlo de esta forma:
sudo apt install ipset
Una vez instalado, ya podremos comenzar a utilizarlo.
El siguiente script que hemos programado consiste en bloquear un país o varios, añadiendo todas sus subredes descargadas de IPdeny e incorporando todas las subredes a un ipset para posteriormente llamar a ese ipset y bloquearlo en iptables. De esta forma, iptables será mucho más eficiente que si lo haces sin la extensión de ipset.
#!/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
Ahora podremos ver el estado de iptables poniendo lo siguiente, y veremos que hace uso del ipset configurado:
iptables -L
Para ver el estado del ipset, ponemos lo siguiente:
ipset list
Siempre que queramos bloquear un nuevo país, tendrás que ejecutar nuevamente el script y automáticamente todo el contenido de ipset se borrará y se añadirán desde cero todas las nuevas subredes. Esto es lo más recomendable porque continuamente se están actualizando las diferentes bases de datos de direcciones IP y rangos de los diferentes países. Debemos advertir que países como China tiene un gran número de bloques de direcciones IP, por lo que tardará varios minutos en aplicar todas las reglas al cortafuegos, si probamos con solo «ad» es casi instantáneo porque tenemos muy pocos.
Gracias a este script, si nuestro servicio a través de Internet sólo trabaja en España, podemos banear todos los demás países, pero debemos tener en cuenta que si un usuario de España usa un proxy o VPN de otro país, no le dejaremos acceso.
Configuración de iptables con ipset para permitir España y bloquear el resto
En este script haremos justo lo contrario que el anterior, lo que haremos es descargar la base de datos de direcciones IP de España, la añadiremos al ipset nuevo creado y permitiremos el acceso. Por defecto, lo que hará es denegar todo el resto del tráfico de otros países. Si tu negocio está en España y solamente quieres que se conecten en España, esto es lo mejor y más eficiente que puedes hacer porque solamente estarás permitiendo un país y no bloqueando el resto del mundo específicamente.
#!/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
Ahora podremos ver el estado de iptables poniendo lo siguiente, y veremos que hace uso del ipset configurado:
iptables -L
Para ver el estado del ipset, ponemos lo siguiente:
ipset list
Tal y como habéis visto, es realmente sencillo bloquear o permitir un país haciendo uso de ipset de iptables, además, es mucho más eficiente que hacerlo directamente con iptables, por lo que os recomendamos usar siempre ipset para esta clase de acciones.
Configuración de nftables para bloquear países
nftables es el nuevo firewall de Linux, mejor, más rápido y más intuitivo que el popular iptables que siempre hemos utilizado. nftables ya se encuentra instalado en la mayoría de distribuciones de Linux aunque utilicemos sintaxis de iptables. Si utilizas las últimas versiones de Debian, ya estarás usando nftables sin saberlo, pero no podremos hacer uso de la sintaxis propia de nftables.
Para poder utilizar al 100% nftables, tendremos que instalarlo directamente desde los repositorios, ejecutando la siguiente orden:
sudo apt install nftables
Una vez instalado, podremos empezar a configurar nftables con el comando «nft». La sintaxis es radicalmente distinta a iptables, por lo que, si no lo has usado, necesitarás un tiempo para adaptarte a la nueva sintaxis.
El siguiente script que hemos programado consiste en bloquear un país o varios, añadiendo todas sus subredes descargadas de IPdeny e incorporando todas las subredes al nftables para bloquearlo en el firewall. Debemos recordar que nftables es mucho más eficiente que iptables, y funcionará realmente bien.
#!/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
Ahora podremos ver el estado de nftables poniendo lo siguiente, y veremos que hace uso del ipset configurado:
nft list ruleset
Configuración de nftables para permitir países
El siguiente script que hemos programado consiste en permitir un país, añadiendo todas sus subredes descargadas de IPdeny e incorporando todas las subredes al nftables para permitirlo en el firewall, el resto del tráfico estará denegado. Debemos recordar que nftables es mucho más eficiente que iptables, y funcionará realmente bien.
#!/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
Ahora podremos ver el estado de nftables poniendo lo siguiente, y veremos que hace uso del ipset configurado:
nft list ruleset
Hasta aquí hemos llegado con este tutorial sobre iptables y ipset para bloquear o permitir IPs de diferentes países, también hemos visto cómo hacerlo con nftables, el nuevo firewall de Linux con una nueva sintaxis que es mucho más intuitiva, pero que nos costará algo de trabajo acostumbrarnos si siempre hemos trabajado con iptables.
Fuente: https://www.redeszone.net/tutoriales/seguridad/bloquear-ip-paises-firewall-iptables-nftables/