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 Free, viene 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
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.