Saltar a contenido

Bloqueo de Países con GeoIP2

Controla el acceso por país con la precisa base de datos de geolocalización de MaxMind.


  • Bloquear Actores Maliciosos


    Detén ataques de países de alto riesgo antes de que lleguen a tu aplicación

  • Listo para Cumplimiento


    Aplica restricciones geográficas para GDPR, licencias o requisitos legales

  • Cero Sobrecarga


    Búsqueda en base de datos en memoria—sin llamadas a API externas ni latencia

  • Datos Precisos


    Bases de datos GeoIP2 de MaxMind con un 99.8% de precisión por país


Requisitos Previos

Necesitarás una cuenta gratuita de MaxMind para descargar las bases de datos GeoIP2:

  1. Regístrate en maxmind.com/en/geolite2/signup
  2. Genera una clave de licencia en tu cuenta
  3. Guárdala para la configuración de actualización automática

Configuración Rápida

Paso 1: Instalar el Módulo GeoIP2

# Instalar el repositorio de GetPageSpeed
dnf -y install https://extras.getpagespeed.com/release-latest.rpm

# Instalar el módulo GeoIP2 y el actualizador automático de base de datos
dnf -y install nginx-module-geoip2 geoipupdate

Habilita en /etc/nginx/nginx.conf:

load_module modules/ngx_http_geoip2_module.so;

Paso 2: Configurar Actualizaciones de Base de Datos

Edita /etc/GeoIP.conf:

AccountID YOUR_ACCOUNT_ID
LicenseKey YOUR_LICENSE_KEY
EditionIDs GeoLite2-Country GeoLite2-City

Descarga las bases de datos:

geoipupdate

Habilita actualizaciones automáticas semanales:

systemctl enable --now geoipupdate.timer

Paso 3: Configurar NGINX

Agrega a tu bloque http en /etc/nginx/nginx.conf:

# Cargar bases de datos GeoIP2
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
    auto_reload 60m;
    $geoip2_country_code country iso_code;
    $geoip2_country_name country names en;
}

Paso 4: Bloquear Países

# Bloquear Rusia, China, Corea del Norte
map $geoip2_country_code $blocked_country {
    default 0;
    RU 1;
    CN 1;
    KP 1;
}

server {
    # ... tu configuración del servidor ...

    if ($blocked_country) {
        return 403;
    }
}
# Solo permitir EE. UU., Reino Unido, Canadá, Australia
map $geoip2_country_code $allowed_country {
    default 0;
    US 1;
    GB 1;
    CA 1;
    AU 1;
}

server {
    # ... tu configuración del servidor ...

    if ($allowed_country = 0) {
        return 403;
    }
}
map $geoip2_country_code $blocked_country {
    default 0;
    RU 1;
    CN 1;
}

server {
    error_page 403 /geo-blocked.html;

    location = /geo-blocked.html {
        internal;
        root /var/www/error-pages;
    }

    if ($blocked_country) {
        return 403;
    }
}

Recarga NGINX:

nginx -t && systemctl reload nginx

Pruebas

# Probar con una IP conocida
curl -H 'X-Forwarded-For: 8.8.8.8' https://example.com
# Debería funcionar (Google DNS - EE. UU.)

curl -H 'X-Forwarded-For: 77.88.8.8' https://example.com
# Debería ser bloqueado (DNS de Yandex - Rusia, si RU está bloqueado)

Pruebas Locales

Las IPs locales/privadas devuelven códigos de país vacíos. Prueba con IPs públicas reales.


Uso Avanzado

Usar IP Real del Cliente Detrás de Proxy/CDN

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
    $geoip2_country_code source=$http_x_forwarded_for country iso_code;
}

Reglas Diferentes para Diferentes Rutas

# Bloquear en todas partes excepto en la API
location / {
    if ($blocked_country) {
        return 403;
    }
    # ... configuración normal ...
}

location /api/ {
    # API accesible desde cualquier lugar
    # ... configuración de la API ...
}

Registrar Información del País

log_format geo '$remote_addr - $geoip2_country_code - $request';
access_log /var/log/nginx/geo.log geo;

Limitar la Tasa por País

# Límites más estrictos para países de alto riesgo
map $geoip2_country_code $limit_key {
    default $binary_remote_addr;
    RU $binary_remote_addr$geoip2_country_code;
    CN $binary_remote_addr$geoip2_country_code;
}

limit_req_zone $limit_key zone=geo_limit:10m rate=10r/s;

Códigos de País Comunes

Código País Código País
US Estados Unidos DE Alemania
GB Reino Unido FR Francia
CA Canadá AU Australia
CN China RU Rusia
IN India BR Brasil
JP Japón KR Corea del Sur
KP Corea del Norte IR Irán

Lista completa: ISO 3166-1 alpha-2


Solución de Problemas

El país siempre está vacío
  • Verifica que la ruta de la base de datos exista: ls -la /usr/share/GeoIP/
  • Verifica que el módulo esté cargado: nginx -V 2>&1 | grep geoip2
  • Verifica que la IP no sea privada/local
Se detecta un país incorrecto
  • Actualiza la base de datos: geoipupdate
  • Verifica si está detrás de un CDN/proxy (usa X-Forwarded-For)
  • Precisión de MaxMind: ~99.8% para países
La base de datos no se actualiza
  • Verifica el temporizador: systemctl status geoipupdate.timer
  • Verifica las credenciales en /etc/GeoIP.conf
  • Ejecuta manualmente: geoipupdate -v

Relacionado