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.
Los cortafuegos hoy en día son fundamentales para estar correctamente protegido, en sistemas operativos basados en Linux todos usan iptables (antiguo) o el nuevo nftables. Estos softwares nos permitirán filtrar todo el tráfico adecuadamente para protegernos de posibles ataques. En RedesZone hemos realizado algunos scripts usando tanto iptables como nftables, con el objetivo de que puedas bloquear masivamente todos los países que quieras, o bien permitas solamente ciertos países donde esté tu negocio.
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. Esto es lo más eficiente, porque con cada nueva regla que tengamos en iptables o nftables, más lento será el sistema a la hora de gestionar el tráfico de red, y más consumo de recursos tendremos. Hay que tener presente que, todas las reglas se validan de forma secuencial, desde arriba hasta abajo. Por este motivo, es totalmente necesario que configures las reglas más específicas en la parte superior, y las más generales en la parte inferior.
Implementación en empresas
Implementar este tipo de bloqueos en el sector empresarial, tiene muchos beneficios más allá de los accesos a Internet. Estas son esenciales para que la seguridad de todo el sistema, sea la adecuada. Se trata de herramientas, que son de mucha ayuda para los administradores de la red. Algunos de los motivos son:
- Seguridad de la red: El firewall es la primera línea de defensa contra los ataques. Disponer de configuraciones de nftables e iptables, permite que se puedan establecer reglas mucho más precisas para mantener el tráfico bajo control. Lo cual hace que los recursos de la empresa se mantengan a salvo.
- Defensa contra ataques específicos: Ambas herramientas bien configuradas, nos ayudan a mitigar ciertos ataques como las inundaciones DDoS. Pero también los escaneos de puertos, y otros patrones que se pueden generar por el tráfico sospechoso.
- Segmentación de la red: Cuando se trata de una gran organización, es muy común realizar segmentos de la red para poder separar y aislar diferentes departamentos o funciones. Estableciendo las reglas adecuadas, podemos asegurarnos de que el tráfico solo fluye por donde es necesario. Y que las zonas más sensibles, se encuentren totalmente protegidas.
- Controles de acceso: No todo el contenido y servicios debe estar disponible para todo el mundo. Por lo cual es importante mantener controlados todos los accesos en la red. Mediante estos dos sistemas, se pueden generar restricciones en los accesos como pueden ser los servicios críticos. O incluso asignarlo por direcciones IP específicas.
- Auditoría y Monitorización: Con las capacidades que nos proporcionan ambos sistemas, se pueden realizar monitorizaciones en los intentos de acceso u otros eventos que ocurran en la red. Todos los registros recogidos, son de vital importancia para las auditorías de seguridad, y para prevenir posibles accidentes.
- Gestión de ancho de banda: El ancho de banda es algo que se debe mantener controlado, de lo contrario se pueden producir retrasos y ralentizaciones. Con iptables y nftables, podemos ayudar a la gestión de esta capacidad, asegurando que los recursos de red se utilicen de la forma más eficiente posible.
¿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.
Es muy importante configurar un crontab con estos scripts, para que vayan renovando continuamente las direcciones IP nuevas y los nuevos rangos de IP.
Configuración de iptables con ipset para bloquear países
iptables siempre ha sido 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. Nftables es el sistema predeterminado en las distribuciones modernas como Debian 12 y siguientes, CentOS 8 o superior, y Ubuntu 22.04 y posteriores.
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. Cuando se trabaja con iptables y tenemos listas de más de 500 rangos CIDR, es recomendable ir directamente a ipset porque es mucho más eficiente, reduciendo el consumo de CPU hasta en un 70% en comparación con iptables.
| Función | iptables (con ipset) | nftables (nativo) | Ventaja clave de nftables |
|---|---|---|---|
| Creación de conjunto de IPs | ipset create paises hash:net | nft add set inet filter paises { type ipv4_addr; } | Funcionalidad integrada, sin dependencias externas. |
| Añadir un rango | ipset add paises 192.168.1.0/24 | nft add element inet filter paises { 192.168.1.0/24 } | Sintaxis más atómica y clara. |
| Aplicar regla de bloqueo | iptables -A INPUT -m set --match-set paises src -j DROP | nft add rule inet filter input ip saddr @paises drop | Sintaxis más legible y directa. |
| Rendimiento (aprox.) | Bueno, pero depende de un subsistema externo (ipset). | Superior. El kernel procesa los sets de forma más eficiente. | Hasta un 40% más rápido en la evaluación de grandes conjuntos de reglas. |
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 IPTABLES), 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="https://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="https://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="https://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="https://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.
Adaptación para IPv6: Consideraciones clave
El crecimiento de IPv6 continúa pero de forma muy lenta, en un futuro es posible que tengas que adaptar estos scripts. Actualmente en España, el uso de IPv6 es completamente residual, así que la mayoría de personas siguen usando el protocolo IPv4. Un aspecto importante, es que en IPv6 los rangos son mucho más extensos y jerárquicos. En el caso de que quieras implementar estos mismos scripts pero para IPv6, tendrás que entrar directamente en la web de IPDeny para IPv6.
Una vez que hayas indicado la dirección de descarga de IPv6, tendrás que adaptar el script para ejecutar iptables o nftables pero con el protocolo IPv6, a continuación, os indicamos algunas órdenes que tendrás que usar:
ipset create pais_ipv6 hash:net family inet6
Posteriormente, tendrás que usar iptables para realizar el bloqueo correspondiente.
En el caso de usar nftables, aquí tienes un ejemplo de orden que tendrás que usar:
nft add set ip6 filter paises_ipv6 { type ipv6_addr; flags interval; }
Como podéis ver, las órdenes a utilizar son similares, pero tendrás que usar el protocolo IPv6 para ello.
Ejemplo de automatización con Crontab
Para garantizar que tus listas de IP estén siempre actualizadas, la automatización es esencial, para poder hacer esto, basta con incorporarlo en un crontab para que así no tengamos problemas de direcciones IP desactualizadas. Los pasos que debes hacer son los siguientes:
- Guarda tu script (por ejemplo, el de bloqueo con nftables) en una ruta como «/usr/local/bin/actualizar_geobloqueo.sh» y dale permisos de ejecución con «chmod +x /usr/local/bin/actualizar_geobloqueo.sh».
- Abre el editor de crontab con el comando «crontab -e».
- Añade la siguiente línea para que el script se ejecute todos los días a las 3:00 AM, una hora de bajo tráfico:
0 3 * * * /usr/local/bin/actualizar_geobloqueo.sh >> /var/log/geobloqueo_update.log 2>&1
Esta línea ejecutará el script y guardará cualquier salida o error en el fichero «/var/log/geobloqueo_update.log» para su posterior revisión.
