2026年11月12日

2026年11月12日

Limitare l’accesso per paese con Nginx GeoIP2 e GeoLite2

Questo articolo è un'edizione localizzata dell'originale giapponese. Leggi l'originale in giapponese

Per limitare l'accesso per paese in Nginx, si usano il modulo per GeoIP2 (ngx_http_geoip2_module) e il database GeoLite2 di MaxMind: un blocco geoip2 mette il codice del paese in una variabile e map decide cosa consentire e cosa negare. È la procedura valida a novembre 2026. La vecchia procedura che si trova negli articoli datati, cioè scaricare con wget un file .dat di GeoLite, non funziona più perché quella distribuzione è terminata.

Ecco subito il riepilogo.

  • Il vecchio ngx_http_geoip_module (GeoIP Legacy) non è più utilizzabile per nuove installazioni, perché MaxMind ha chiuso la distribuzione dei dati nel vecchio formato. Si passa a GeoIP2 (formato .mmdb).
  • GeoLite2 è gratuito, ma richiede un account MaxMind e una chiave di licenza; download e aggiornamenti si fanno con geoipupdate.
  • In Nginx, un blocco geoip2 crea una variabile come $geoip2_country_code, map assegna 0 / 1 (l'equivalente di allow / deny) e in una location si risponde con return 403.
  • Se il sito passa da una CDN come Cloudflare, bisogna prima ripristinare l'IP reale del visitatore con real_ip_header; altrimenti tutti vengono riconosciuti come provenienti dal paese della CDN.
  • Il blocco per paese è solo un aiuto per ridurre gli attacchi e si aggira con VPN o relay. Più che sull'intero sito pubblico, conviene usarlo sulla pagina di login e sull'area di amministrazione.
Flusso di configurazione di Nginx GeoIP2: registrazione su MaxMind, download del database con geoipupdate, caricamento del modulo, controllo con geoip2 e map, limitazione nella location

Differenza tra il vecchio geoip e GeoIP2

Voce ngx_http_geoip_module (vecchio) ngx_http_geoip2_module (GeoIP2)
Formato dei dati GeoIP Legacy (.dat) GeoIP2 (.mmdb)
Dati gratuiti Terminati (distribuzione chiusa nel 2019) GeoLite2 (richiede account e chiave di licenza)
Libreria necessaria libGeoIP libmaxminddb
Come ottenere il modulo Incluso in Nginx (--with-http_geoip_module) Modulo di terze parti leev/ngx_http_geoip2_module. Su Debian / Ubuntu esiste il pacchetto
Variabili Fisse, come $geoip_country_code Le nomini tu nel blocco geoip2

Se nella configurazione esistente usi geoip_country, il database non viene più aggiornato e quindi il riconoscimento è ormai datato. Ne approfitto per consigliarti di passare a GeoIP2.

Passo 1: registrati su MaxMind e crea la chiave di licenza

  1. Crea un account gratuito dalla pagina di MaxMind dedicata a GeoLite2.
  2. Dopo il login, genera una License Key nell'area di gestione dell'account (la chiave viene mostrata solo al momento della creazione, quindi annotala).
  3. Come database usa GeoLite2-Country se ti serve solo il paese, oppure GeoLite2-City se ti serve anche la città. Per il blocco per paese basta Country.

Le condizioni d'uso (GeoLite2 End User License Agreement) contengono regole su ridistribuzione e visualizzazione dei dati. Se li usi solo per le decisioni sul tuo server rientri di norma nei limiti, ma leggi le condizioni al momento della registrazione.

Passo 2: scarica e aggiorna il database con geoipupdate

GeoLite2 viene aggiornato periodicamente, quindi non scaricarlo a mano: usa geoipupdate (documentazione di geoipupdate).

# Debian / Ubuntu
sudo apt install geoipupdate

# Famiglia RHEL (AlmaLinux / Rocky Linux): da EPEL
sudo dnf install geoipupdate

Scrivi ID account e chiave di licenza nel file di configurazione /etc/GeoIP.conf.

AccountID 123456
LicenseKey la-chiave-che-hai-generato
EditionIDs GeoLite2-Country
# La cartella di destinazione è quella predefinita della distribuzione (Debian / Ubuntu: /var/lib/GeoIP, altrove spesso /usr/share/GeoIP).
# Per cambiarla: DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/   # se c'è GeoLite2-Country.mmdb, è andato a buon fine

Il pacchetto di geoipupdate include già l'esecuzione periodica tramite timer di systemd o cron (verificalo con systemctl list-timers | grep geoip). Se manca, aggiungi un cron con cadenza di circa una volta a settimana.

Passo 3: installa il modulo GeoIP2 in Nginx

Debian / Ubuntu (Nginx da apt)

sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/   # viene creato 50-mod-http-geoip2.conf
nginx -t

Nginx dei pacchetti di nginx.org o compilato dai sorgenti

Dopo aver installato libmaxminddb, compila un modulo dinamico dai sorgenti della stessa versione di Nginx in esecuzione.

sudo apt install libmaxminddb-dev   # famiglia RHEL: libmaxminddb-devel
cd /usr/local/src
git clone https://github.com/leev/ngx_http_geoip2_module
curl -LO https://nginx.org/download/nginx-1.26.3.tar.gz   # la versione deve corrispondere a nginx -v
tar xzf nginx-1.26.3.tar.gz && cd nginx-1.26.3
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
make modules
sudo cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/

Caricalo all'inizio di nginx.conf (con i pacchetti viene inserito automaticamente).

load_module modules/ngx_http_geoip2_module.so;

Passo 4: metti il codice del paese in una variabile e decidi cosa consentire o negare

Scrivi la configurazione nel blocco http. Il blocco geoip2 inserisce il codice del paese in una variabile e map assegna 1 ai paesi consentiti e 0 a tutti gli altri.

http {
    geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        auto_reload 60m;
        $geoip2_country_code country iso_code;
    }

    # Paesi autorizzati all'area di amministrazione (codici ISO 3166-1 di 2 lettere)
    map $geoip2_country_code $admin_allowed {
        default 0;
        JP      1;
        ""      1;   # Se non è riconoscibile (per esempio IP privato) si consente. Per negare, metti 0
    }
}

auto_reload è l'intervallo con cui viene riletto il database sostituito da geoipupdate, senza riavviare Nginx.

Passo 5: limita solo login e area di amministrazione di WordPress

Ecco un esempio che non limita le pagine pubbliche e filtra per paese solo wp-login.php e /wp-admin/. Scrivilo nel blocco server.

server {
    # ... configurazione esistente ...

    location = /wp-login.php {
        if ($admin_allowed = 0) { return 403; }
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
    }

    location ^~ /wp-admin/ {
        if ($admin_allowed = 0) { return 403; }
        # se admin-ajax.php è usato da plugin esterni, consentilo in una location separata
        location ~ \.php$ {
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
        }
    }
}

La combinazione di if e return è una forma che Nginx gestisce in modo sicuro. /wp-admin/admin-ajax.php può essere chiamato senza login da funzioni delle pagine pubbliche (moduli, scroll infinito e simili), quindi decidi in base alle funzioni del tuo sito se escluderlo dalla limitazione.

Applica e verifica:

sudo nginx -t && sudo systemctl reload nginx

# Dal tuo paese: risponde 200 o 302
curl -sI https://example.com/wp-login.php | head -1
# Verifica del riconoscimento (esempio: scrivere il codice del paese nel log)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';

Per vedere come appare il sito dall'estero, accedi a wp-login.php con una VPN di un'altra nazione o da un servizio di monitoraggio all'estero e verifica che risponda 403.

Se il sito passa da una CDN (Cloudflare e simili)

Con una CDN $remote_addr diventa l'IP della CDN e tutti vengono riconosciuti come provenienti dal paese della CDN. Prima di tutto ripristina l'IP reale del visitatore con ngx_http_realip_module (modulo realip).

# Esempio per Cloudflare. Aggiorna periodicamente l'elenco dagli IP Ranges ufficiali di Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... elenca tutti gli intervalli di Cloudflare ...
real_ip_header   CF-Connecting-IP;

geoip2 per impostazione predefinita guarda $remote_addr, quindi il riconoscimento avviene sull'IP reale sostituito da realip. Anche Cloudflare ha un controllo degli accessi per paese (regole personalizzate del WAF): se usi Cloudflare, limitare lì è più semplice che farlo in Nginx. Leggi anche Configurare Cloudflare su WordPress.

I limiti del blocco per paese

  • Il riconoscimento GeoIP è una stima basata sui dati di registrazione degli indirizzi IP e si aggira con VPN, proxy e relay da cloud esteri.
  • Con le reti mobili o aziendali l'IP può essere associato a un paese diverso da quello reale. Può anche capitare, a livello operativo, che un amministratore in trasferta all'estero resti chiuso fuori.
  • Per questo il blocco per paese va usato come aiuto per ridurre i tentativi di forza bruta sul login, insieme all'autenticazione a due fattori, al limite dei tentativi di accesso e alla protezione di wp-admin con autenticazione Basic.

Domande frequenti

Che differenza c’è tra il modulo geoip e il modulo geoip2 di Nginx?

Il vecchio modulo geoip legge dati in formato GeoIP Legacy (.dat), ma MaxMind ha chiuso la distribuzione di quel formato. Il modulo geoip2 (ngx_http_geoip2_module) legge l'attuale formato .mmdb e permette di usare i dati gratuiti di GeoLite2. Per le nuove configurazioni usa geoip2.

GeoLite2 è gratuito? Serve la registrazione?

È gratuito, ma servono un account MaxMind e una chiave di licenza. Download e aggiornamenti periodici si fanno con geoipupdate. La vecchia procedura che scarica direttamente senza chiave non funziona.

Limitando per paese si evitano gli accessi non autorizzati a WordPress?

Riduce i tentativi di forza bruta, ma si aggira con una VPN o con un relay da un server estero, quindi non si può dire che lo impedisca. Abbinalo a limite dei tentativi di accesso, autenticazione a due fattori, autenticazione Basic e simili.

Con Cloudflare tutti risultano dello stesso paese

Succede perché con una CDN l'origine della connessione è l'IP della CDN. Ripristina l'IP reale con set_real_ip_from e real_ip_header CF-Connecting-IP prima del controllo. Puoi anche limitare per paese con il WAF di Cloudflare.

Con GeoLite2-City posso limitare anche per città?

Puoi mettere in variabili anche i codici di città e regione, ma la precisione a livello di città è inferiore a quella del paese e i falsi riconoscimenti rischiano di tagliare fuori utenti legittimi. Per il controllo degli accessi è più prudente fermarsi al livello del paese.

Riepilogo

  • Oggi il blocco per paese in Nginx si fa con GeoIP2 (ngx_http_geoip2_module + GeoLite2 .mmdb) e i dati si aggiornano con geoipupdate.
  • Metti il codice del paese in una variabile con geoip2, decidi cosa consentire o negare con map e usa return 403 nelle location di wp-login.php e /wp-admin/.
  • Se c'è una CDN, ripristina prima l'IP reale e usa il blocco per paese come misura di supporto insieme all'autenticazione a due fattori e simili.

Articoli correlati

Fonti: ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module

Cronologia degli aggiornamenti: 2026-11-09 revisione completa (la vecchia procedura GeoLite non più distribuita è stata sostituita da quella con GeoIP2 e geoipupdate, con aggiunta di un esempio di limitazione dell'area di amministrazione di WordPress e dell'avvertenza sulle CDN). Questo articolo è pubblicato da WordPress Hakase (Lightscend Inc.).

Domande su WordPress? Chi pubblica questo sito ha sede in Giappone e risponde in giapponese. Contatti (in giapponese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲