Nginx: come integrare la geolocalizzazione

Parole
Marco Bellomo
Immagini
Elisa Del Maestro
Tempo di lettura
5

Anche se è un aspetto da usare con criterio, sapere da dove proviene un IP può essere molto utile

L

Geolocalizzazione ed etica

Quando parliamo di geolocalizzazione, uno degli scenari di utilizzo più spesso prospettatiè quello di bloccare il contenuto di certi siti in base al paese: anche se fatta con intenzioni spesso sensate, bloccare contenuti a secondo dell’appartenenza geografica non è esattamente lo spirito con cui è nato internet. 

La geolocalizzazione può infatti essere usata in modo etico e vantaggioso per fornire informazioni personalizzate al visitatore, puntando a rendere più trasparente e ricca l’esperienza. Se abbiamo per esempio un e-commerce in cui i costi per una spedizione verso la Cina sono molto rilevanti, tanto da non essere facilmente presi in considerazione, la soluzione non dovrebbe mai essere quella di bloccare l’accesso del sito a quel paese, ma piuttosto avvisare i visitatori provenienti da tale locazione geografica delle difficoltà nello spedire in quel paese, vista la natura dei costi o del prodotto in sé.

Quello della geolocalizzazione sugli e-commerce meriterebbe in realtà un discorso a sé. Consultando il Regolamento (UE) 2018/302  è facilmente intuibile che non si è obbligati a fornire servizi o prodotti in tutti gli stati, a livello etico ( e legale), ma che vietare completamente o parzialmente l’accesso all’informazione e alla usabilità dell'interfaccia online a seconda dell’IP del visitatore, è una cosa con cui discutere attentamente con un consulente.
Casi specifici per contenuti che violino particolare norme in particolari nazioni naturalmente devono essere considerati ugualmente con attenzione.

Una chiara eccezione temporanea si può fare se il blocco geografico è volto a bloccare un attacco informatico. Se leggendo i log di sistema infatti si vede che da un certo paese arrivano attacchi ddos o similari, come misura immediata si può anche pensare di bloccare temporaneamente accesso da IP di quel paese; la scelta più etica e giusta resta però quella di bloccare gli IP specifici portatori dell’attacco, anche se per fare ciò bisogna avere un sistema un po’ più complesso.

Quello che vale assolutamente per gli e-commerce, vale sicuramente in misura minore per qualsiasi sito e dato il perfezionamento della legislazione e la riflessione in atto è sempre consigliabile pianificare al meglio questo aspetto.

Come integrare la Geolocalizzazione con NGINX

Come sempre, scavando a fondo, si possono trovare una marea di sistemi per integrare la geolocalizzazione su Nginx. Tra i vari sistemi oggi analizzeremo l’utilizzo del modulo GeoiP, in combinazione ai database di geolocalizzazione di Maxmind.

Cos’è Maxmind?

MaxMind è un'azienda specializzata nella fornitura di database di geolocalizzazione per l'identificazione della posizione geografica degli indirizzi IP. Offre una vasta gamma di prodotti, tra cui il database GeoIP2, che fornisce informazioni dettagliate sulla posizione geografica degli indirizzi IP, tra cui il paese, la regione, la città, il codice postale e le coordinate geografiche.

Noi useremo in questo esempio il GeoLite2 Free Geolocation Data che è gratuito, anche se come avvisa la stessa azienda, sicuramente meno accurato della soluzione GeoIP2 databases. Per completezza, è corretto ricordare che anche la versione free, GeoLite2 Freeviene aggiornata 2 volte a settimana. 

Anche per poter scaricare la versione freedovremo comunque registrarci sul sito di Maxmind, dando alcune informazioni su di noi, principalmente nome e cognome, uso che intendiamo fare del loro database e altre solite domande. 

Una volta registrati, potremo andarci a scaricare il database, facendo attenzione a scaricare quello con estensione .mmdb

Iniziamo a creare la struttura dockerizzata

Il nostro esempio prevede la creazione della seguente struttura di cartelle e file 

Ngix e geolocalizzazione

Dentro dist metteremo una nostra index.html di prova da servire direttamente.

Dentro local.conf definiremo un paio di blocchi server e sfrutteremo la variabile $geoip2_data_country_iso_code per i nostri usi.

Dentro nginx.conf noi includeremo il modulo ngx_http_geoip2_module.so e quindi valorizzeremo la variabile $geoip2_data_country_iso_code che useremo poi in local.conf.

GeoLite2-Country.mmdb è ovviamente il database che abbiamo scaricato.

In docker-compose.yml definiremo il nostro container Nginx, dandogli la nostra build specifica definita in nginx.Dockerfile e definendo un paio di volumi per includere il local.conf e la nostra index.html di esempio

local.conf

server {
       listen 80;
       return 404;
}
# configuration of the server
server {
   # the port your site will be served on
   listen      80;
   # the domain name it will serve for
   server_name DOMINIOAPIACIMENTO;   
  location / {
       add_header  Content-Type  text/plain;
       #if ($geoip2_data_country_iso_code = IT) {
       #    return 200 "Benvenuto dall'Italia";
       #}
       return 200 "Il tuo country code è: $geoip2_data_country_iso_code";
   }


}

nginx.conf

load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
   worker_connections  1024;
}

http {
   include  /etc/nginx/mime.types;
   default_type  application/octet-stream;
   sendfile        on;
   keepalive_timeout  65;
  
   geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_data_country_iso_code country iso_code;
   }

   log_format  main  '$geoip2_data_country_iso_code $remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';
   access_log  /var/log/nginx/access.log  main;
   include /etc/nginx/conf.d/*.conf;
}

nginx.Dockerfile

ARG NGINX_VERSION=1.19.2

FROM nginx:$NGINX_VERSION

ARG NGINX_VERSION=1.19.2
ARG GEOIP2_VERSION=3.3

RUN mkdir -p /var/lib/GeoIP/

RUN apt-get update \
   && apt-get install -y \
       build-essential \
       libpcre++-dev \
       zlib1g-dev \
       libgeoip-dev \
       libmaxminddb-dev \
       wget \
       git

RUN cd /opt \
   && git clone --depth 1 -b $GEOIP2_VERSION --single-branch https://github.com/leev/ngx_http_geoip2_module.git \
   && wget -O - http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz | tar zxfv - \
   && mv /opt/nginx-$NGINX_VERSION /opt/nginx \
   && cd /opt/nginx \
   && ./configure --with-compat --add-dynamic-module=/opt/ngx_http_geoip2_module \
   && make modules

FROM nginx:$NGINX_VERSION

COPY --from=0 /opt/nginx/objs/ngx_http_geoip2_module.so /usr/lib/nginx/modules

RUN apt-get update \
   && apt-get install -y --no-install-recommends --no-install-suggests libmaxminddb0 \
   && apt-get clean \
   && rm -rf /var/lib/apt/lists/* \
   && chmod -R 644 /usr/lib/nginx/modules/ngx_http_geoip2_module.so

COPY ./docker/GeoLite2-Country.mmdb /var/lib/GeoIP/
COPY ./docker/nginx-conf/nginx.conf /etc/nginx/

docker-compose.yml

version: '3'
services:
   nginx:
       build:
           context: .
           dockerfile: ./docker/nginx.Dockerfile
       restart: always
       ports:
           - "80:80"
       volumes:    
           - ./docker/conf.d:/etc/nginx/conf.d
           - ./dist:/var/www/html
       networks:
           app-net:
               aliases:
                   - DOMINIOAPIACIMENTO  
networks:
   app-net:
       driver: bridge

deploy.sh

#!/bin/bash
docker-compose -f docker-compose.yml up -d --build

In conclusione

Quello che abbiamo analizzato insieme è un esempio completo, che pecca però nell’aggiornamento del database geografico. Se volessimo sfruttare realmente questo esempio, dovremmo considerare di creare un meccanismo per cui, tramite le nostre credenziali, scarichiamo un paio di volte a settimana il database aggiornato. Se volessimo integrare questo meccanismo, potremmo sicuramente partire dalla documentazione di maxmind su questo punto. 

Se poi volessimo usare un sistema del genere realmente in produzione, dovremmo considerare, a seconda della nostra reale esigenza di accuratezza nella geolocalizzazione, la possibilità di prendere la versione a pagamento.

Analizza la tua presenza online.

Scrivici per una consulenza gratuita



Richiedi consulenza

Marco Bellomo

Chairman

A diciott'anni pensavo che sarei diventato uno scrittore di fama mondiale e che avrei dominato le classifiche con il mio oscuro ciclo fantasy. A ventiquattr'anni pensavo che il PHP fosse immortale. Oggi mi piace non dare nulla per scontato, forse perché ...