Agregue GeoIP a NGINX

Nginx con función de bloqueo por medio de geoip2.

Si tienes instalado el modulo pagespeed mira antes esto https://topete.gitbook.io/contenido/v/anadir-modulo-pagespeed-a-nginx-proxy-manager/

pagina geoip2

Los archivos necesarios están en este enlace. Aunque en el tutorial se describe como crearlos, de esta manera podrás aprender un poco más, si no conoces cómo hacerlo manualmente.

https://www.dropbox.com/sh/uzlx0a0vcynkz63/AADn-7e0CRiVDPzkxQdx4Od9a?dl=0

GeoIP es una técnica para localizar a un usuario en función de su dirección IP. Para ello, nos apoyaremos en las bases de datos que Maxmind pone a su disposición de forma gratuita: GeoLite2. Estas bases gratuitas son menos precisas que sus versiones de pago, pero serán en gran medida suficientes para nuestro uso.

requisitos previos:

Necesitaremos dos Docker para esta función. Es posible que funcione con otro Docker de proxy inverso, pero no he probado con otro, este proxy inverso tiene la ventaja de ser fácil agregar dominios a través de GUI

  • Nginx-Proxy-Manager-Official.

  • Geoipupdate.

Instalacion Nginx-Proxy-Manager-Official.

Primeramente, instalaremos NGINX, en la misma plantilla podemos ya crear alguna carpeta que será necesaria para el funcionamiento correcto.

Como vemos la carpeta se llamará /modules, (asegurate crearla con este nombre) estará en las siguientes rutas.

Container Path=>/etc/nginx/modules

Host Path=>/mnt/user/appdata/Nginx-Proxy-Manager-Official/modules.

Si no vamos a usar IPv6 podemos desactivarla directamente en la plantilla, esto es opcional.

Antes de aplicar e instalar el Docker cambiaremos los puertos por defecto de la plantilla 80, 443 a los que queráis, como por ejemplo 80 => 8081, 443 => 4433, ya que los marcara como en uso y no se instalara el Docker.

Instalación Geoipupdate.

Para obtener las bases Geoip2 gratuitas de Maxmind, primero debes registrarte en su sitio. https://www.maxmind.com/en/home

Crea una cuenta y una vez que haya sido validada, mediante el correo que te enviaran, podrás iniciar sesión para generar una clave de licencia, que se utilizará más adelante.

¡Atención! Toma nota de la identificación de la cuenta y la clave de licencia (esto ya no será visible).

Una vez hemos obtenido nuestras credenciales podemos iniciar la configuración en la plantilla de Geoipupdate. Solo hay que realizar dos cosas importantes. La carpeta donde se guardarán las bases de datos debemos incorporarla dentro de la carpeta de NGINX. Lo demás es intuitivo no creo necesario explicar donde poner la claves obtenidas en el registro.

/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/geoip2

La otra acción importante es definir que bases de datos vamos a descargar y actualizar.

GeoLite2-City GeoLite2-Country GeoLite2-ASN (separadas por un espacio).

  • GeoLite2-ASN : Información sobre el ISP propietario de la IP.

  • GeoLite2-Country : geolocalización de IP a nivel de país.

  • GeoLite2-City : Geolocalización de IP a nivel de ciudad. (Incluye nivel de país)

Ahora instalamos el Docker y verificamos que la carpeta se ha creado correctamente, y se han descargando las bases de datos correspondientes. Podemos parar el Docker.

Esta es parte más fácil, a continuación, empezaremos a realizar los scripts para el correcto funcionamiento del conjunto.

Preparativos para compilar módulos.

Los módulos que compilaremos serán almacenados en la carpeta que creamos con anterioridad en NGINX en la carpeta /modules. Pero los scripts los crearemos y guardaremos en la carpeta /data

Cuando hice las pruebas, tuve problemas creando los archivos fuera de Unraid y luego subiéndolos, quizás el formato donde los creaba no era el correcto. Aunque los archivos que se incorporan en la descarga son los que están funcionando actualmente en mi proxy, es por ello que opté por la opción de crearlos mediante el editor de archivos vi en la consola de Unraid, es muy fácil puedes echar un vistazo cómo funciona vi en este video que encontré. Siempre es bueno aprender algo más. https://www.youtube.com/watch?v=VO6EoN-a7QA

Crearemos un script entrypoint.sh que colocaremos en la carpeta de /data de NGINX. Nos permitirá instalar los paquetes y archivos necesarios para luego compilar los módulos para nuestra versión de NGINX.

1 abrimos la consola de Unraid, y navegamos hasta la carpeta deseada donde crearemos el archivo.

cd /mnt/user/appdata/Nginx-Proxy-Manager-Official/data

2 tecleamos: vi entrypoint.sh

Se abrirá el editor de archivos vi vacío, copiamos el script de abajo. Guardamos y salimos de vi.

3 tecleamos: chmod +x entrypoint.sh esto es para darle permisos de ejecución.

#!/bin/bash
apt-get update
apt-get install -y libmaxminddb0 libmaxminddb-dev --no-install-recommends apt-utils

echo "=>Check for GeoIP modules files and version flag..."
set -- /etc/nginx/modules/ngx_geoip2_*
if [[ -f /etc/nginx/modules/ngx_http_geoip2_module.so && -f /etc/nginx/modules/ngx_stream_geoip2_module.so && -f "$1" ]]; then
        moduleversion=$(echo $1|cut -d "-" -f2|grep -oP '^\d*\.\d*\.\d*')
        ngxversion=$(/etc/nginx/bin/openresty -v 2>&1|cut -d "/" -f2|grep -oP '^\d*\.\d*\.\d*')
        if [ "$moduleversion" != "$ngxversion" ]; then
                echo "!=>GeoIP modules ($moduleversion) and nginx ($ngxversion) version mismatch !"
                echo "!=>Starting compilation !"
                /data/compile-geoip2.sh
        else
                echo "=>GeoIP modules found and version match nginx !"
        fi
else
        echo "!=>No GeoIP module found !"
        echo "!=>Starting compilation !"
        /data/compile-geoip2.sh
fi

apt-get clean
rm -rf /var/lib/apt/lists/*

set -- /etc/nginx/modules/ngx_geoip2_*
moduleversion=$(echo $1|cut -d "-" -f2|grep -oP '^\d*\.\d*\.\d*')
ngxversion=$(/etc/nginx/bin/openresty -v 2>&1|cut -d "/" -f2|grep -oP '^\d*\.\d*\.\d*')
echo "### GeoIP Modules $moduleversion - Nginx $ngxversion ###"
echo "### Starting NPM orignal entrypoint ###"
/init

Hacemos la misma operación para el archivo compile-geoip2.sh

1 abrimos la consola de Unraid, y navegamos hasta la carpeta deseada donde crearemos el archivo.

cd /mnt/user/appdata/Nginx-Proxy-Manager-Official/data

2 tecleamos: vi compile-geoip2.sh

Se abrirá el editor de archivos vi vacío, copiamos el script de abajo. Guardamos y salimos de vi.

3 tecleamos: chmod +x compile-geoip2.sh esto es para darle permisos de ejecución.

#!/bin/bash
apt-get install -y wget libpcre3 libpcre3-dev libssl-dev zlib1g-dev

ngxversion=openresty-$(/etc/nginx/bin/openresty -v 2>&1|cut -d "/" -f2)

mkdir /tmp/compile && cd /tmp/compile
wget https://openresty.org/download/$ngxversion.tar.gz
tar xvf $ngxversion.tar.gz

mkdir /tmp/compile/$ngxversion/modules
cd /tmp/compile/$ngxversion/modules
git clone https://github.com/leev/ngx_http_geoip2_module.git

cd ../bundle/nginx-$(/etc/nginx/bin/openresty -v 2>&1|cut -d "/" -f2|grep -oP '^\d*\.\d*\.\d*')
export LUAJIT_LIB="/etc/nginx/luajit/lib/"
export LUAJIT_INC="../LuaJIT-*/src/"
COMPILEOPTIONS=$(/etc/nginx/bin/openresty -V 2>&1|grep -i "arguments"|cut -d ":" -f2-)
eval ./configure $COMPILEOPTIONS --add-dynamic-module=../../modules/ngx_http_geoip2_module
make

cp -f objs/ngx_stream_geoip2_module.so /etc/nginx/modules/
cp -f objs/ngx_http_geoip2_module.so /etc/nginx/modules/
rm -f /etc/nginx/modules/ngx_geoip2_*
touch /etc/nginx/modules/ngx_geoip2_$ngxversion

rm -rf /tmp/compile	

Para cargar los módulos compilados en NGINX cuando se inicie, simplemente cree un archivo geoip2.conf en la carpeta /modules de NGINX con las siguientes líneas. Este archivo no necesitara permisos chmod +x

load_module /etc/nginx/modules/ngx_http_geoip2_module.so;
load_module /etc/nginx/modules/ngx_stream_geoip2_module.so;

En este paso vamos a agregar una instrucción a la plantilla de NGINX, de manera que siempre ejecute el archivo entrypoint.sh antes de iniciar la imagen. De esta manera no aseguramos de su correcto funcionamiento ante actualizaciones del contenedor.

Lo añadiremos al principio, sin borrar nada.

--entrypoint=/data/entrypoint.sh

A continuación, vamos a poner en marcha esta primera parte del tutorial.

Lo primero arrancar el Docker NGINX, es posible que os aparecerá algún error, pero vamos a solucionar esto.

1 entramos en la consola del Docker NGINX y tecleamos el comando cd con ello nos situamos en la raíz.

Ahora actualizaremos todo con apt update && apt upgrade cuando nos pregunte sobre continuar pulsamos enter

Esperamos pacientemente, una vez acaba reiniciamos el Docker y observamos el log para verificar que todo esta correcto, es posible que todavía aparezca algún error, cierra el log y vuelve abrirlo.

Deberías ver esto:

Como veras IPv6 aparece disable, como ya comenté, es opcional.

De momento, si todo ha ido bien, tendremos la primera parte realizada, ahora falta que bloquee y eso todavía no lo hace, en la segunda parte del tutorial realizaremos esa tarea, pero primero debes asegurarte de que la primera parte no contiene errores y todo funciona correctamente.

Verifica que se han creado los archivos correctamente en /modules.

Los archivos creados con el editor vi y mira sus permisos

Que el Docker geoipupdate crea las bases de datos en la carpeta correspondiente.

Estas fotos te ayudaran a ver los permisos y si el archivo es ejecutable (en verde ejecutable.XX*

Segunda parte del tutorial.

En esta segunda parte realizaremos las configuraciones y añadiremos diversos archivos para poder realizar los bloqueos.

El primer paso es crear una carpeta donde introduciremos los archivos correspondientes para configurar los bloqueos, esta carpeta la llamaremos /custom y la añadiremos en la siguiente ruta.

/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/custom

En la carpeta /custom creamos un archivo de la misma manera que hemos creado los anteriores, desde la consola del propio Unraid.

cd/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/custom

vim http_top.conf

y copiamos el siguiente texto:

geoip2 /data/geoip2/GeoLite2-Country.mmdb {
    auto_reload 60m;
    $geoip2_metadata_country_build metadata build_epoch;
    $geoip2_data_country_code default=ES source=$remote_addr country iso_code;
    $geoip2_data_country_name country names es;
}
geoip2 /data/geoip2/GeoLite2-City.mmdb {
    auto_reload 60m;
    $geoip2_metadata_city_build metadata build_epoch;
    $geoip2_data_city_name default=Madrid city names es;
}

Esta configuración permitirá cargar el archivo GeoLite2-Country.mmdb y GeoLite2-City.mmdb previamente descargado y extraer en variables el código del país, el nombre del país y el nombre de la ciudad.

Ten en cuenta que en el archivo hay que cambiar la parte del bloqueo local geo $allowed_ip, hay debes cambiarlo por la ip de tu red local.

Mas adelante añadiremos mas líneas a este archivo.

Definición de IPs a bloquear según origen.

Para bloquear direcciones IP de ciertos países, puede optar por dos enfoques:

Bloquee todos los países y permita solo algunos, agregando las siguientes líneas al archivo http_top.conf:

geo $allowed_ip {
default no; # On interdit par défaut
192.168.1.0/24 yes; # On autorizada red local
}
map $geoip2_data_country_code $allowed_country {
default $allowed_ip;
FR yes; # On autorise les IP Française
BE yes; # On autorise les IP Belges
}

Permita todos los países y bloquee solo algunos, agregando las siguientes líneas al archivo http_top.conf:

geo $allowed_ip {
default yes; # On autorise par défaut
192.168.1.0/24 yes; # On autorizada red local
}
map $geoip2_data_country_code $allowed_country {
default $allowed_ip;
CN no; # On interdit les IP Chinoises
RU no; # On interdit les IP Russes
}

Como veras la diferencia es o permitir ES yes con lo que todos los demás países quedan bloqueados. O denegar ES no con lo que todos los países quedan permitidos a excepción de los indicados en el archivo. Puedes obtener los códigos de los diferentes países desde esta Url https://en-m-wikipedia-org.translate.goog/wiki/ISO_3166-1?_x_tr_sl=auto&_x_tr_tl=es&_x_tr_hl=es#Officially_assigned_code_elements

Por ejemplo, si solo queremos permitir acceso desde España el archivo http_top.conf completo sería el siguiente.

geoip2 /data/geoip2/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_data_country_code default=ES source=$remote_addr country iso_code;
$geoip2_data_country_name country names es;
}
geoip2 /data/geoip2/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city_name default=Madrid city names es;
}
geo $allowed_ip {
default no; # On interdit par défaut
192.168.1.0/24 yes; # On autorizada red local
}
map $geoip2_data_country_code $allowed_country {
default $allowed_ip;
ES yes; # On autorizadas España
}

Configuración de bloqueo

Una vez que hemos definido lo que queremos bloquear/permitir, solo queda hacerlo efectivo.

Para hacer esto, agregue estas líneas a un archivo de configuración:

if ($allowed_country = no) {
return 404;
}

El archivo en el que añadir estas líneas depende del nivel en el que se quiera realizar el bloqueo:

  • Bloqueo general: debe crear un archivo server_proxy.conf con este contenido en la carpeta /mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/custom

  • Bloqueo a nivel de cada Proxy Host: Este contenido debe ser agregado en la configuración avanzada (Custom Nginx Configuration) de cada host (NPM web interface).

Con esto ya tendríamos configurado el bloqueo, pero para saber si los bloqueos están siendo efectivos, lo mejor es crear unos logs por cada host proxy, para ello realizamos la siguiente configuración.

agreguemos un nuevo formato de registro al archivo http_top.conf

log_format proxy_geo escape=json '[$time_local] [Client $remote_addr] [$allowed_country $geoip2_data_country_code $geoip2_data_country_name $geoip2_data_city_name] "$http_user_agent" '
                                 '$upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_referer"';

La información registrada por NPM es la misma que por defecto, solo hemos agregado la información de GeoIP:

[$allowed_country $geoip2_data_country_code $geoip2_data_country_name $geoip2_data_city_name].

Es decir, si la solicitud está autorizada o no, el código de dos letras del país, el nombre del país, el nombre de la ciudad.

Luego agreguemos en la configuración avanzada (Configuración personalizada de Nginx) de cada host (interfaz web de NPM), el siguiente código que generará el archivo de registro en el formato correcto para cada solicitud en este host:

access_log /data/logs/proxy-host-%HOSTID%_access-geo.log proxy_geo;

Reemplazando %HOSTID% con la identificación del servidor proxy que está modificando. (la manera de saber que id corresponde con cada host es la siguiente.

Para saber que %HOSTID% tiene cada dominio solo tiene que abrir la interfaz web de NGINX. pulsas sobre la pestaña Host => Proxy Hosts, y como veras en la foto ese numero es el id que tienes que poner sustituyendo %HOSTID%, en este caso 1

access_log /data/logs/proxy-host-%HOSTID%_access-geo.log proxy_geo;

access_log /data/logs/proxy-host-1_access-geo.log proxy_geo;

Puede ver el nuevo archivo de registro en vivo con el siguiente comando, recuerda cambiar %HOSTID%

tail -f /mnt/user/appdata/Nginx-Proxy-Manager-Official/data/logs/proxy-host-%HOSTID%_access-geo.log

sí recibes un error de archivo no encontrado es posible que no se halla generado aun ninguna entrada o tengas otra ruta de acceso al archivo de log

Y después de este tocho de instrucciones y configuraciones tenemos listo nuestro proxy para rechazar conexiones no deseadas.

Última actualización