Enviado por admin el
En el mundo de la seguridad de servidores y la administración de redes, una de las estrategias más efectivas para reducir ataques y tráfico no deseado es el bloqueo geográfico de IPs. En este artículo te mostraré cómo implementar un sistema de bloqueo basado en GeoIP utilizando xtables-addons en AlmaLinux 9, incluyendo la solución a los problemas de compilación más comunes.
¿Qué es xtables-addons?
Xtables-addons es un conjunto de extensiones para iptables/netfilter que añade funcionalidades adicionales no incluidas en el kernel estándar de Linux. Una de sus características más potentes es el módulo GeoIP, que permite crear reglas de firewall basadas en la ubicación geográfica de las direcciones IP.
Ventajas del bloqueo con GeoIP
- Simplicidad: Una sola regla puede bloquear millones de IPs
- Eficiencia: Consume menos recursos que grandes listas de ipset
- Mantenimiento: Las bases de datos se actualizan fácilmente
- Flexibilidad: Permite bloquear o permitir países específicos
Requisitos previos
Antes de comenzar, asegúrate de tener:
- AlmaLinux 9 instalado y actualizado
- Acceso root o sudo
- Conexión a Internet para descargar paquetes
- iptables instalado (no firewalld)
Paso 1: Preparación del sistema
Primero, instalamos todas las dependencias necesarias:
# Actualizar el sistema
dnf update -y
# Instalar EPEL repository
dnf install epel-release -y
# Instalar dependencias de compilación
dnf install kernel-devel kernel-headers gcc make automake autoconf libtool -y
# Instalar herramientas adicionales
dnf install iptables iptables-services wget unzip perl-Text-CSV_XS -y
# Deshabilitar firewalld si está activo
systemctl stop firewalld
systemctl disable firewalld
# Habilitar iptables
systemctl enable iptables
systemctl start iptables
Paso 2: Descargar xtables-addons
Descargamos la última versión estable de xtables-addons:
# Crear directorio de trabajo
cd /usr/src
# Descargar xtables-addons
wget https://inai.de/files/xtables-addons/xtables-addons-3.24.tar.xz
# Extraer el archivo
tar xf xtables-addons-3.24.tar.xz
cd xtables-addons-3.24
Paso 3: Aplicar el parche para AlmaLinux 9
AlmaLinux 9 utiliza un kernel 5.14+, que tiene cambios en la API que causan errores de compilación. Necesitamos aplicar un parche:
# Crear el archivo de parche
cat > fix-kernel-5.14.patch << 'EOF'
--- a/extensions/compat_xtables.h
+++ b/extensions/compat_xtables.h
@@ -27,7 +27,11 @@
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
-# define pde_data(inode) PDE_DATA(inode)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
+# define pde_data(inode) ((inode)->i_private)
+# else
+# define pde_data(inode) PDE_DATA(inode)
+# endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
EOF
# Aplicar el parche
patch -p1 < fix-kernel-5.14.patch
¿Por qué es necesario este parche?
El kernel 5.14 cambió la forma en que se accede a los datos privados de las entradas /proc. La función PDE_DATA() fue reemplazada por acceso directo a inode->i_private. Este parche detecta la versión del kernel y usa el método apropiado.
Paso 4: Compilar e instalar xtables-addons
Ahora procedemos con la compilación:
# Configurar el paquete
./configure
# Compilar
make
# Instalar
make install
# Cargar el módulo del kernel
modprobe xt_geoip
# Verificar que el módulo se cargó correctamente
lsmod | grep xt_geoip
Si ves una salida similar a xt_geoip 16384 0, el módulo se cargó correctamente.
Paso 5: Descargar la base de datos GeoIP
Ahora necesitamos descargar y preparar la base de datos de ubicaciones geográficas:
# Crear directorio para la base de datos
mkdir -p /usr/share/xt_geoip
# Navegar al directorio de scripts GeoIP
cd /usr/src/xtables-addons-3.24/geoip
# Descargar la base de datos (esto puede tardar unos minutos)
./xt_geoip_dl
# Construir la base de datos binaria
./xt_geoip_build -D /usr/share/xt_geoip *.csv
# Verificar que se crearon los archivos
ls /usr/share/xt_geoip/ | wc -l
Deberías ver un número mayor a 200, representando los diferentes países y territorios.
Paso 6: Crear reglas de firewall con GeoIP
Ahora viene la parte interesante: crear reglas basadas en países.
Bloquear un país específico
# Bloquear todo el tráfico desde China
iptables -I INPUT -m geoip --src-cc CN -j DROP
# Bloquear tráfico saliente hacia Rusia
iptables -I OUTPUT -m geoip --dst-cc RU -j DROP
Bloquear múltiples países
# Bloquear varios países simultáneamente
iptables -I INPUT -m geoip --src-cc CN,RU,KP,IR -j DROP
Crear una lista blanca (whitelist)
# Permitir solo tráfico desde España, Italia y Francia
iptables -I INPUT -m geoip ! --src-cc ES,IT,FR -j DROP
Logging antes de bloquear
Es útil registrar los intentos de conexión antes de bloquearlos:
# Registrar y luego bloquear
iptables -I INPUT -m geoip --src-cc CN -j LOG --log-prefix "GeoBlock-CN: "
iptables -I INPUT -m geoip --src-cc CN -j DROP
Paso 7: Guardar la configuración
Para que las reglas persistan después de un reinicio:
# Guardar las reglas de iptables
service iptables save
# Asegurar que iptables inicie con el sistema
systemctl enable iptables
Paso 8: Script de gestión automatizada
Para facilitar la gestión, creamos un script de administración:
cat > /usr/local/bin/geoip-manager.sh << 'SCRIPT'
#!/bin/bash
# Script de gestión de GeoIP para iptables
# Autor: Tu nombre
# Fecha: $(date +%Y-%m-%d)
ACTION=$1
COUNTRIES=$2
LOG_FILE="/var/log/geoip-manager.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
usage() {
cat << EOF
Uso: $0 {block|unblock|list|status|update} [COUNTRY_CODES]
Comandos:
block CODES Bloquear países (ej: CN,RU,KP)
unblock CODES Desbloquear países
list Mostrar reglas GeoIP activas
status Mostrar estadísticas de bloqueo
update Actualizar base de datos GeoIP
Ejemplos:
$0 block CN,RU # Bloquea China y Rusia
$0 unblock CN # Desbloquea China
$0 list # Lista reglas activas
$0 update # Actualiza base de datos
Códigos de países comunes:
CN=China, RU=Rusia, US=Estados Unidos, BR=Brasil
KP=Corea del Norte, IR=Irán, IN=India, VN=Vietnam
EOF
exit 1
}
block_countries() {
log "Bloqueando países: $1"
# Bloquear tráfico entrante
iptables -I INPUT -m geoip --src-cc $1 -j LOG --log-prefix "GeoBlock-$1: " --log-level 4
iptables -I INPUT -m geoip --src-cc $1 -j DROP
# Opcional: bloquear tráfico saliente
# iptables -I OUTPUT -m geoip --dst-cc $1 -j DROP
service iptables save
log "Países bloqueados correctamente: $1"
}
unblock_countries() {
log "Desbloqueando países: $1"
# Eliminar reglas de bloqueo
iptables -D INPUT -m geoip --src-cc $1 -j LOG --log-prefix "GeoBlock-$1: " --log-level 4 2>/dev/null
iptables -D INPUT -m geoip --src-cc $1 -j DROP 2>/dev/null
iptables -D OUTPUT -m geoip --dst-cc $1 -j DROP 2>/dev/null
service iptables save
log "Países desbloqueados: $1"
}
list_rules() {
echo "=== Reglas GeoIP INPUT ==="
iptables -L INPUT -n -v --line-numbers | grep geoip
echo ""
echo "=== Reglas GeoIP OUTPUT ==="
iptables -L OUTPUT -n -v --line-numbers | grep geoip
}
show_status() {
echo "=== Estado del sistema GeoIP ==="
echo ""
echo "Módulo del kernel:"
lsmod | grep xt_geoip || echo " ¡ADVERTENCIA! Módulo no cargado"
echo ""
echo "Base de datos GeoIP:"
DB_COUNT=$(ls /usr/share/xt_geoip/ 2>/dev/null | wc -l)
echo " Países en base de datos: $DB_COUNT"
echo ""
echo "Reglas activas:"
RULES_COUNT=$(iptables -L INPUT -n | grep -c geoip)
echo " Total de reglas GeoIP: $RULES_COUNT"
echo ""
echo "Estadísticas de bloqueo (INPUT):"
iptables -L INPUT -n -v | grep geoip | awk '{print " Paquetes bloqueados: " $1 ", Bytes: " $2}'
}
update_geoip() {
log "Iniciando actualización de base de datos GeoIP"
# Backup de la base actual
if [ -d "/usr/share/xt_geoip" ]; then
BACKUP_DIR="/usr/share/xt_geoip.backup.$(date +%Y%m%d_%H%M%S)"
cp -r /usr/share/xt_geoip $BACKUP_DIR
log "Backup creado en: $BACKUP_DIR"
fi
# Descargar nueva base de datos
cd /usr/src/xtables-addons-3.24/geoip
./xt_geoip_dl
if [ $? -eq 0 ]; then
# Construir base de datos
./xt_geoip_build -D /usr/share/xt_geoip *.csv
if [ $? -eq 0 ]; then
log "Base de datos GeoIP actualizada correctamente"
# Limpiar backups antiguos (más de 30 días)
find /usr/share -name "xt_geoip.backup.*" -mtime +30 -exec rm -rf {} \; 2>/dev/null
else
log "ERROR: Fallo al construir la base de datos"
# Restaurar backup
rm -rf /usr/share/xt_geoip
mv $BACKUP_DIR /usr/share/xt_geoip
exit 1
fi
else
log "ERROR: Fallo al descargar la base de datos"
exit 1
fi
}
# Verificar que se ejecuta como root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Este script debe ejecutarse como root"
exit 1
fi
# Procesar comando
case "$ACTION" in
block)
if [ -z "$COUNTRIES" ]; then
echo "ERROR: Debes especificar los códigos de países"
usage
fi
block_countries $COUNTRIES
;;
unblock)
if [ -z "$COUNTRIES" ]; then
echo "ERROR: Debes especificar los códigos de países"
usage
fi
unblock_countries $COUNTRIES
;;
list)
list_rules
;;
status)
show_status
;;
update)
update_geoip
;;
*)
usage
;;
esac
SCRIPT
# Hacer el script ejecutable
chmod +x /usr/local/bin/geoip-manager.sh
Paso 9: Uso del script de gestión
El script que acabamos de crear simplifica enormemente la gestión:
# Bloquear China y Rusia
geoip-manager.sh block CN,RU
# Ver estadísticas
geoip-manager.sh status
# Listar reglas activas
geoip-manager.sh list
# Desbloquear un país
geoip-manager.sh unblock CN
# Actualizar base de datos GeoIP
geoip-manager.sh update
Paso 10: Automatizar actualizaciones de la base de datos
Las bases de datos GeoIP deben actualizarse periódicamente:
# Crear script de actualización automática
cat > /etc/cron.monthly/update-geoip << 'EOF'
#!/bin/bash
/usr/local/bin/geoip-manager.sh update >> /var/log/geoip-update.log 2>&1
EOF
# Hacer ejecutable
chmod +x /etc/cron.monthly/update-geoip
También puedes usar crontab para actualizaciones más frecuentes:
# Editar crontab
crontab -e
# Agregar línea para actualizar el primer día de cada mes a las 3 AM
0 3 1 * * /usr/local/bin/geoip-manager.sh update >> /var/log/geoip-update.log 2>&1
Paso 11: Cargar módulo automáticamente al inicio
Para asegurar que el módulo GeoIP se cargue en cada reinicio:
# Agregar módulo a la carga automática
echo "xt_geoip" >> /etc/modules-load.d/xtables-addons.conf
# Verificar
cat /etc/modules-load.d/xtables-addons.conf
Códigos de países más utilizados
Aquí tienes una lista de códigos ISO que puedes usar:
| Código | País | Código | País |
|---|---|---|---|
| CN | China | US | Estados Unidos |
| RU | Rusia | BR | Brasil |
| KP | Corea del Norte | IN | India |
| IR | Irán | VN | Vietnam |
| TR | Turquía | ID | Indonesia |
| UA | Ucrania | PK | Pakistán |
| DE | Alemania | JP | Japón |
| FR | Francia | KR | Corea del Sur |
| ES | España | IT | Italia |
| GB | Reino Unido | MX | México |
Casos de uso prácticos
Proteger servidor VoIP
Si tienes un servidor VoIP (Kamailio, Asterisk, FreeSWITCH), puedes bloquear países de donde no esperas llamadas:
# Permitir solo España, Italia y países europeos
geoip-manager.sh block CN,RU,KP,IR,VN,IN,BR,TR
Proteger servidor web
Para un sitio web que solo atiende clientes locales:
# Permitir solo España y países vecinos
iptables -A INPUT -p tcp --dport 80 -m geoip ! --src-cc ES,FR,PT,IT -j DROP
iptables -A INPUT -p tcp --dport 443 -m geoip ! --src-cc ES,FR,PT,IT -j DROP
service iptables save
Proteger SSH
Bloquear acceso SSH desde países específicos:
# Bloquear SSH desde China y Rusia
iptables -I INPUT -p tcp --dport 22 -m geoip --src-cc CN,RU -j DROP
service iptables save
Monitorización y logs
Ver intentos de conexión bloqueados
# Ver logs en tiempo real
tail -f /var/log/messages | grep GeoBlock
# Ver estadísticas de bloqueos
grep "GeoBlock" /var/log/messages | wc -l
Analizar países bloqueados
# Crear script de análisis
cat > /usr/local/bin/geoip-stats.sh << 'EOF'
#!/bin/bash
echo "=== Estadísticas de bloqueo GeoIP ==="
echo ""
echo "Top 10 países bloqueados hoy:"
grep "GeoBlock" /var/log/messages | \
grep "$(date '+%b %e')" | \
awk -F'GeoBlock-' '{print $2}' | \
awk -F':' '{print $1}' | \
sort | uniq -c | sort -rn | head -10
EOF
chmod +x /usr/local/bin/geoip-stats.sh
Troubleshooting (Resolución de problemas)
El módulo no carga
# Verificar si el módulo existe
find /lib/modules -name "xt_geoip.ko"
# Recargar módulo
modprobe -r xt_geoip
modprobe xt_geoip
# Ver errores del kernel
dmesg | grep -i geoip
Las reglas no funcionan
# Verificar que la base de datos existe
ls -lh /usr/share/xt_geoip/
# Verificar reglas de iptables
iptables -L INPUT -n -v | grep geoip
# Probar manualmente
iptables -I INPUT -m geoip --src-cc CN -j LOG --log-prefix "TEST-GeoIP: "
# Intenta conectar desde una IP china y revisa los logs
tail -f /var/log/messages
Error de compilación persiste
Si el parche no funciona, compila sin el módulo problemático:
cd /usr/src/xtables-addons-3.24
make clean
./configure --without-pknock
make
make install
Consideraciones de seguridad
- No dependas solo de GeoIP: Los atacantes pueden usar VPNs o proxies
- Combina con otras medidas: Usa fail2ban, rate limiting, etc.
- Actualiza regularmente: Las asignaciones de IPs cambian
- Cuidado con bloqueos excesivos: Podrías bloquear tráfico legítimo
- Mantén logs: Monitorea lo que estás bloqueando
Rendimiento
GeoIP es muy eficiente:
- Impacto mínimo: Las búsquedas son en memoria
- Escalable: Puede manejar millones de conexiones
- Mejor que ipset grandes: Para bloqueos masivos por país
Actualización del sistema
Cuando actualices el kernel de AlmaLinux:
# Después de actualizar el kernel, recompila xtables-addons
cd /usr/src/xtables-addons-3.24
make clean
./configure
make
make install
# Recargar módulo
modprobe -r xt_geoip
modprobe xt_geoip
Desinstalación (si es necesario)
Si necesitas eliminar xtables-addons:
# Eliminar reglas de iptables
iptables -F
# Descargar módulo
modprobe -r xt_geoip
# Desinstalar
cd /usr/src/xtables-addons-3.24
make uninstall
# Limpiar archivos
rm -rf /usr/share/xt_geoip
rm -f /etc/modules-load.d/xtables-addons.conf
Conclusión
El bloqueo geográfico con xtables-addons y GeoIP es una herramienta poderosa para administradores de sistemas en AlmaLinux 9. Aunque requiere compilación y configuración inicial, los beneficios en seguridad y reducción de tráfico no deseado son significativos.
Este método es especialmente útil para:
- Servidores VoIP que reciben ataques de países específicos
- Servicios web con audiencia local
- Protección de servicios administrativos (SSH, panels)
- Reducción de spam y escaneos automatizados
Recuerda mantener actualizada la base de datos GeoIP y combinar esta técnica con otras medidas de seguridad para una protección integral.
Referencias y recursos adicionales
- Sitio oficial de xtables-addons
- Documentación de iptables
- Base de datos IP2Location
- Códigos de países ISO 3166-1
Nota del autor: Este tutorial ha sido probado en AlmaLinux 9.x con kernel 5.14+. Si encuentras algún problema o tienes sugerencias, no dudes en dejar un comentario. Se agradece el apoyo de Claude Sonnet 4.5
Comentarios recientes