# Agregue GeoIP a NGINX

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

{% hint style="success" %}
Dificultad tutorial: Media Conocimientos a tener: Medios
{% endhint %}

{% hint style="info" %}
Si tienes instalado el modulo pagespeed mira antes esto <https://topete.gitbook.io/contenido/v/anadir-modulo-pagespeed-a-nginx-proxy-manager/>

pagina geoip2
{% endhint %}

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.

![](/files/Rsrd3C2efhPp7qwzxMn8)

* Geoipupdate.

![](/files/iTOvvzPhxSLojf3KFqEA)

#### Instalacion Nginx-Proxy-Manager-Official.&#x20;

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

![](/files/uz2CUlJN0wMMZyaiVwp8)

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

*<mark style="color:blue;">Container Path=>/etc/nginx/modules</mark>*

*<mark style="color:blue;">Host Path=>/mnt/user/appdata/Nginx-Proxy-Manager-Official/modules.</mark>*

{% hint style="info" %}
Si no vamos a usar IPv6 podemos desactivarla directamente en la plantilla, esto es opcional.
{% endhint %}

![](/files/G8WPTXa0vRVGimV8Xzca)

{% hint style="info" %}
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.
{% endhint %}

**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).

![](/files/UBsUAFeQMX0jelYVycff)

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.

![](/files/Xe9TLrUEoUXc8hD3WKKk)

<mark style="color:blue;">/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/geoip2</mark>

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

![](/files/l7feB5y568VFxLWkONiy)

***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*](https://www.youtube.com/watch?v=VO6EoN-a7QA)

Crearemos un script <mark style="color:blue;">**entrypoint**</mark>*<mark style="color:blue;">**.sh**</mark>* 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.

<mark style="color:blue;">**cd /mnt/user/appdata/Nginx-Proxy-Manager-Official/data**</mark>

<mark style="color:blue;">2 tecleamos:</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">**vi entrypoint.sh**</mark>*

<mark style="color:blue;">Se abrirá el editor de archivos vi vacío, copiamos el script de abajo. Guardamos y salimos de vi.</mark>

<mark style="color:blue;">3 tecleamos:</mark> <mark style="color:blue;"></mark>*<mark style="color:blue;">**chmod +x entrypoint.sh**</mark>* <mark style="color:blue;">esto es para darle permisos de ejecución.</mark>

```bash
#!/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 *<mark style="color:blue;">**compile-geoip2.sh**</mark>*

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

<mark style="color:blue;">**cd /mnt/user/appdata/Nginx-Proxy-Manager-Official/data**</mark>

<mark style="color:blue;">2 tecleamos:</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**vi compile-geoip2.sh**</mark>

<mark style="color:blue;">Se abrirá el editor de archivos vi vacío, copiamos el script de abajo. Guardamos y salimos de vi.</mark>

<mark style="color:blue;">3 tecleamos:</mark> <mark style="color:blue;"></mark><mark style="color:blue;">**chmod +x compile-geoip2.sh**</mark> <mark style="color:blue;"></mark><mark style="color:blue;">esto es para darle permisos de ejecución.</mark>

<pre class="language-bash"><code class="lang-bash">#!/bin/bash
apt-get install -y wget libpcre3 libpcre3-dev libssl-dev zlib1g-dev

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

mkdir /tmp/compile &#x26;&#x26; 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>&#x26;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>&#x26;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	
<strong>
</strong>
</code></pre>

Para cargar los módulos compilados en NGINX cuando se inicie, simplemente cree un archivo *<mark style="color:blue;">**geoip2.conf**</mark>* en la carpeta *<mark style="color:blue;">**/modules**</mark>* de NGINX con las siguientes líneas. ***Este archivo no necesitara permisos chmod +x***

```nginx
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.

![](/files/BfeYdxaajyIqBQLtPVtE)

<mark style="color:blue;">**--entrypoint=/data/entrypoint.sh**</mark>

**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 <mark style="color:blue;">**cd**</mark> con ello nos situamos en la raíz.

Ahora actualizaremos todo  con *<mark style="color:blue;">**apt update**</mark>*<mark style="color:blue;">**&#x20;**</mark><mark style="color:blue;">**&&**</mark><mark style="color:blue;">**&#x20;**</mark>*<mark style="color:blue;">**apt upgrade**</mark>* 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:

![](/files/77qCOdD3k6jYkte5qZon) ![](/files/1tuiwUFVlZff9DcJnq22)

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 <mark style="color:blue;">**/modules.**</mark>

![](/files/tmcfk6BdShe1K1NEJno2)

Los archivos creados con el editor vi y mira sus permisos

![](/files/KuxFrAj719AoeAXxbIC3)

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

![](/files/zerbi30x3Cfps8baboJd)

Estas fotos te ayudaran a ver los permisos y si el archivo es ejecutable (en verde <mark style="color:green;">**ejecutable.XX\***</mark>

![](/files/bmctOtTa5xR2QsZ2NocZ)

![](/files/jwGdrxexs8g0DhecBw5c)

**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.

<mark style="color:blue;">**/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/custo**</mark><mark style="color:blue;">m</mark>

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

<mark style="color:blue;">**cd/mnt/user/appdata/Nginx-Proxy-Manager-Official/data/nginx/custom**</mark>

<mark style="color:blue;">**vim http\_top.conf**</mark>

<mark style="color:blue;">y copiamos el siguiente texto:</mark>

```nginx
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.

{% hint style="info" %}
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.*
{% endhint %}

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&#x20;**<mark style="color:blue;">**http\_top.conf**</mark>**:**

<pre class="language-nginx"><code class="lang-nginx"><strong>geo $allowed_ip {
</strong>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
}
</code></pre>

**Permita todos los países y bloquee solo algunos, agregando las siguientes líneas al archivo&#x20;**<mark style="color:blue;">**http\_top.conf**</mark>**:**

```nginx
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.**

```nginx
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:

```nginx
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 *<mark style="color:blue;">**http\_top.conf**</mark>*

```nginx
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"';
```

![](/files/wGmAdrZRwE7zdrQYlwY6)

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;*

{% hint style="warning" %}
si estas usando el docker GoAccess-NPM-Logs, cambia esta ruta. Ejemplo /data/%XXX%/proxy-host-%HOSTID%\_access-geo.log proxy\_geo;

Esto es para evitar errores en goaccess. No existe incorporación entre goaccess y este tutorial. goaccess tiene otra estructura aparte propia.
{% endhint %}

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

![](/files/kjHM4GGz2HFNEyDYlSZ4)

<mark style="color:blue;">access\_log /data/logs/proxy-host-%HOSTID%\_access-geo.log proxy\_geo;</mark>

<mark style="color:blue;">access\_log /data/logs/proxy-host-1\_access-geo.log proxy\_geo;</mark>

![](/files/xo0q1fJ0Jez826nryF56)

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

*<mark style="color:blue;">tail -f /mnt/user/appdata/Nginx-Proxy-Manager-Official/data/logs/proxy-host-%HOSTID%\_access-geo.log</mark>*

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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://topete.gitbook.io/contenido/nginx-geoip2/agregue-geoip-a-nginx.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
