Nginx: Bloquear peticiones según ubicación geográfica con GeoIP

Tengo un servidor Nginx en el que solo quiero tener acceso yo, pero siempre tengo muchas peticiones de otros países (China sobre todo), y es por esto que escribo este articulo, porque me parece interesante bloquear todas las peticiones de fuera de mi país y así reducir la posibilidad de cualquier problema.

Índice:

  1. Requisitos previos
  2. Configurar Nginx
    1. Añadir las bases de datos
    2. Definir países/ciudades a bloquear
    3. Bloquear peticiones
      1. Permitir acceso desde la red local
  3. Resultado

Requisitos previos

Los bloqueos se realizan con el módulo GeoIP, para comprobar si lo tenemos:

nginx -V geoip module

Una vez hayáis comprobado que tenéis el módulo with-http_geoip_module=dynamic, podemos continuar.

Configurar Nginx

Añadir las bases de datos

El módulo GeoIP (ngx_http_geoip_module) necesita unas bases de datos precompiladas de MaxMind que contiene los rangos de IPs por países y ciudades. Para utilizarlas, primero tenemos que descargar las BBDD (bases de datos) en la carpeta /etc/nginx/geoip:

Y ahora las añadimos a Nginx en el archivo /etc/nginx/nginx.conf en el bloque http{}:

Definir países/ciudades a bloquear

Después de añadir las bases de datos, crearemos unas variables (con el módulo map) con los países bloqueados y permitidos en $paises_permitidos:

De esta manera, solo estaríamos permitiendo el acceso a las IPs españolas. Ya que con default no; bloqueamos a todos los países y con  ES yes; permitimos solamente a España.

  • $geoip_country_code → es una variable del módulo GeoIP, nos devuelve un código de país de dos letras, por ejemplo, “RU”, “US”
  • $paises_permitidos → es la variable que estamos creando con los países permitidos

Si quisierais bloquear por ciudades tendríais que utilizar  $geoip_city en vez de  $geoip_country_code y escribir en nombre de la ciudad permitida tal y como dice la documentación.

Bloquear peticiones

El bloqueo se realiza en el bloque server{}:

Con este condicional devolvemos un estado HTTP 444 (estado HTTP especial de Nginx que cierra la conexión sin enviar ninguna cabecera HTTP) a los países de la variable $paises_permitidos que tengan el valor no.

Aplicamos los cambios:

A partir de aquí, ya tendríamos bloqueada la página para todos los países excepto España.

Permitir acceso desde la red local

Igual habéis notado que al entrar a la página desde la red local también nos bloquea las peticiones, esto es porque los rangos de IPs de la red local no están en las bases de datos de MaxMind.

Para solucionarlo, primero tenemos que crear una variable con los rangos de nuestra red local usando el módulo geo:

Y agregar $redes_permitidas con el valor  yes a $paises_permitidos con un condicional en el bloque server{}:

De este modo, estamos simulando que las redes que hemos definido en $redes_permitidas, están en la BBDD de MaxMind. Además reutilizamos el condicional if ($paises_permitidos = no) (que es quien realmente bloquea las peticiones) de nuestro bloque server{}.

Ahora, ya tenemos acceso desde la red local, y ya están bloqueadas las peticiones de fuera de nuestro país.

Resultado

No olvidéis aplicar los cambios después de las configuraciones:


Este es el resultado final del bloque http{}:

nginx geoip block and allow networksY este el del bloque server{} de nuestro dominio:

nginx geoip server block conf

Si alguien hace una petición desde un país que tenemos bloqueado, la respuesta será una como esta:

test geoip

Para cualquier duda podéis preguntar por los comentarios o por el grupo de Telegram de LiGNUx @liGNUx.

¡Hasta la próxima!

Acerca de wakutiteo

Deja una respuesta

avatar
  Suscribirse  
Notificarme las
Suscríbete gratis

Suscríbete gratis

Recibe las últimas noticias y novedades de LiGNUx en tu email.
Sin publicidad, sin Spam.

Gracias por suscribirte a LiGNUx.