2026年11月12日

2026年11月12日

Restringir acesso por país no Nginx com GeoIP2 e GeoLite2

Este artigo é uma edição localizada do original em japonês. Ler o original em japonês

Para restringir o acesso por país no Nginx, o procedimento atual (em novembro de 2026) é usar o módulo GeoIP2 (ngx_http_geoip2_module) com o banco de dados GeoLite2 da MaxMind, guardar o código do país em uma variável com o bloco geoip2 e decidir entre permitir ou negar com map. O passo a passo antigo de "baixar o .dat do GeoLite com wget", que aparece em artigos mais velhos, não funciona mais, porque essa distribuição de dados foi encerrada.

Primeiro, o resumo.

  • O antigo ngx_http_geoip_module (GeoIP Legacy) não serve para novas instalações, porque a MaxMind encerrou a distribuição dos dados nesse formato. Migre para o GeoIP2 (formato .mmdb).
  • O GeoLite2 é gratuito, mas exige uma conta na MaxMind e uma chave de licença; o download e as atualizações são feitos com o geoipupdate.
  • No Nginx, o bloco geoip2 cria uma variável como $geoip2_country_code, o map define 0 / 1 (equivalente a allow / deny) e o location faz return 403.
  • Em sites que passam por uma CDN como a Cloudflare, se você não restaurar antes o IP real do visitante com real_ip_header, todos os acessos serão avaliados como se viessem do país da CDN.
  • A restrição por país é um reforço para reduzir ataques e pode ser contornada com VPN ou proxies. Na prática, vale usá-la só na tela de login e no painel de administração, e não no site público inteiro.
Fluxo de configuração do GeoIP2 no Nginx: cadastro na MaxMind, obtenção do banco de dados com geoipupdate, carregamento do módulo, decisão com geoip2 e map e restrição no location

Diferença entre o geoip antigo e o GeoIP2

Item ngx_http_geoip_module (antigo) ngx_http_geoip2_module (GeoIP2)
Formato dos dados GeoIP Legacy (.dat) GeoIP2 (.mmdb)
Dados gratuitos Encerrado (distribuição terminou em 2019) GeoLite2 (exige conta e chave de licença)
Biblioteca necessária libGeoIP libmaxminddb
Como obter o módulo Incluído no Nginx (--with-http_geoip_module) Módulo de terceiros leev/ngx_http_geoip2_module. Há pacote para Debian / Ubuntu
Variáveis Fixas, como $geoip_country_code Você escolhe os nomes no bloco geoip2

Se a sua configuração atual usa geoip_country, o banco de dados parou de ser atualizado e a identificação já está defasada. Aproveite para migrar para o GeoIP2.

Passo 1: cadastre-se na MaxMind e crie a chave de licença

  1. Crie uma conta gratuita na página do GeoLite2 da MaxMind.
  2. Depois de entrar, gere uma License Key no painel da conta (a chave só é exibida no momento em que é gerada, então anote-a).
  3. Para o banco de dados, use GeoLite2-Country se precisar apenas do país, ou GeoLite2-City se precisar também da cidade. Para restringir por país, o Country basta.

Os termos de uso (GeoLite2 End User License Agreement) trazem regras sobre redistribuição e exibição dos dados. Usá-los apenas para fazer a identificação nos seus próprios servidores costuma estar dentro do permitido, mas confira os termos no momento do cadastro.

Passo 2: baixe e atualize o banco de dados com o geoipupdate

O GeoLite2 é atualizado periodicamente, então use o geoipupdate em vez de baixar à mão (documentação do geoipupdate).

# Debian / Ubuntu
sudo apt install geoipupdate

# Família RHEL (AlmaLinux / Rocky Linux): a partir do EPEL
sudo dnf install geoipupdate

No arquivo de configuração /etc/GeoIP.conf, informe o ID da conta e a chave de licença.

AccountID 123456
LicenseKey sua_chave_de_licenca_aqui
EditionIDs GeoLite2-Country
# O destino é o padrão da distribuição (Debian / Ubuntu usam /var/lib/GeoIP; as demais costumam usar /usr/share/GeoIP).
# Para mudar: DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/   # Se o GeoLite2-Country.mmdb estiver lá, deu certo

O pacote do geoipupdate já vem configurado para rodar periodicamente por um timer do systemd ou pelo cron (confira com systemctl list-timers | grep geoip). Se não houver, adicione uma tarefa do cron cerca de uma vez por semana.

Passo 3: instale o módulo GeoIP2 no Nginx

Debian / Ubuntu (Nginx instalado com apt)

sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/   # O 50-mod-http-geoip2.conf é colocado aqui
nginx -t

Nginx dos pacotes do nginx.org ou compilado a partir do código-fonte

Instale a libmaxminddb e compile o módulo dinâmico a partir do código-fonte da mesma versão do Nginx que está em execução.

sudo apt install libmaxminddb-dev   # Na família 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   # A versão deve corresponder à de 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/

Carregue o módulo no início do nginx.conf (nos pacotes, isso é colocado automaticamente).

load_module modules/ngx_http_geoip2_module.so;

Passo 4: guarde o código do país em uma variável e decida entre permitir e negar

Escreva dentro do bloco http. O bloco geoip2 coloca o código do país em uma variável, e o map atribui 1 aos países permitidos e 0 a todos os outros.

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

    # Países com acesso permitido ao painel (código de 2 letras da ISO 3166-1)
    map $geoip2_country_code $admin_allowed {
        default 0;
        JP      1;
        ""      1;   # Quando não dá para identificar (IP privado etc.), permitir. Use 0 se quiser negar
    }
}

O auto_reload é o intervalo em que o banco de dados substituído pelo geoipupdate é relido sem reiniciar o Nginx.

Passo 5: restrinja apenas a tela de login e o painel do WordPress

Este é um exemplo que não restringe as páginas públicas e limita por país apenas o wp-login.php e o /wp-admin/. Escreva dentro do bloco server.

server {
    # ... configuração existente ...

    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 algum plugin externo usa o admin-ajax.php, libere-o em outro location
        location ~ \.php$ {
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
        }
    }
}

A combinação de if com return é uma forma que o Nginx trata com segurança. O /wp-admin/admin-ajax.php pode ser chamado, sem login, por funções das páginas públicas (como formulários e rolagem infinita), então decida se vai excluí-lo da restrição conforme os recursos do seu site.

Para aplicar e verificar:

sudo nginx -t && sudo systemctl reload nginx

# A partir do seu país: retorna 200 ou 302
curl -sI https://example.com/wp-login.php | head -1
# Verificação da identificação (exemplo que grava o código do país no log)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';

Para ver como o site aparece no exterior, acesse o wp-login.php por uma VPN com ponto de saída em outro país ou por um serviço de monitoramento fora do país e confirme que a resposta é 403.

Quando o site passa por uma CDN (como a Cloudflare)

Com uma CDN, o $remote_addr passa a ser o IP da CDN e todos os visitantes são avaliados como se viessem do país da CDN. Restaure antes o IP real do visitante com o ngx_http_realip_module (módulo realip).

# Exemplo da Cloudflare. Atualize a lista de IPs periodicamente a partir de IP Ranges, no site oficial da Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... liste todos os intervalos da Cloudflare ...
real_ip_header   CF-Connecting-IP;

Por padrão, o geoip2 olha o $remote_addr, de modo que a identificação usa o IP real já substituído pelo realip. A própria Cloudflare também tem controle de acesso por país (regras personalizadas do WAF); se você já usa a Cloudflare, é mais simples restringir por lá do que no Nginx. Veja também Como configurar a Cloudflare no WordPress.

Limites da restrição por país

  • A identificação do GeoIP é uma estimativa baseada nos dados de registro do endereço IP e pode ser contornada com VPN, proxies ou retransmissão por nuvens no exterior.
  • Em redes móveis e corporativas, o acesso pode ser atribuído a um país diferente do real. Também pode acontecer o problema operacional de bloquear um administrador que está viajando ao exterior.
  • Por isso, use a restrição por país como um reforço para reduzir tentativas de login por força bruta, combinada com autenticação em dois fatores, limite de tentativas de login e proteção do wp-admin com autenticação Basic.

Perguntas frequentes

Qual é a diferença entre o módulo geoip e o módulo geoip2 do Nginx?

O módulo geoip antigo lê dados no formato GeoIP Legacy (.dat), mas a MaxMind encerrou a distribuição desse formato. O módulo geoip2 (ngx_http_geoip2_module) lê o formato atual .mmdb e permite usar os dados gratuitos do GeoLite2. Em novas configurações, use o geoip2.

O GeoLite2 é gratuito? É preciso se cadastrar?

É gratuito, mas exige uma conta na MaxMind e a emissão de uma chave de licença. O download e a atualização periódica são feitos com o geoipupdate. O procedimento antigo, que baixava diretamente sem usar a chave, não funciona mais.

Restringir por país impede logins indevidos no WordPress?

Ajuda a reduzir tentativas de força bruta, mas, como pode ser contornada por VPN ou retransmissão por servidores no exterior, não dá para dizer que impede. Combine com limite de tentativas de login, autenticação em dois fatores, autenticação Basic e outras medidas.

Usando a Cloudflare, todos os visitantes aparecem no mesmo país

Isso acontece porque, com a CDN, a origem da conexão passa a ser o IP da CDN. Restaure o IP real com set_real_ip_from e real_ip_header CF-Connecting-IP antes de fazer a identificação. Também é possível restringir por país no WAF da Cloudflare.

Com o GeoLite2-City dá para restringir até a cidade?

É possível guardar também os códigos de cidade e região em variáveis, mas a precisão no nível de cidade é menor que no nível de país, e as identificações erradas facilitam bloquear usuários legítimos. Para o controle de acesso, o mais seguro é ficar no nível de país.

Resumo

  • A restrição por país no Nginx hoje é feita com o GeoIP2 (ngx_http_geoip2_module + GeoLite2 .mmdb), e os dados são atualizados com o geoipupdate.
  • Guarde o código do país em uma variável com o geoip2, decida entre permitir e negar com o map e use return 403 nos location do wp-login.php e do /wp-admin/.
  • Atrás de uma CDN, restaure antes o IP real e use a restrição por país como reforço, combinada com autenticação em dois fatores e outras medidas.

Artigos relacionados

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

Histórico de atualizações: 2026-11-09, revisão completa (o procedimento antigo do GeoLite, cuja distribuição foi encerrada, foi substituído pelo procedimento com GeoIP2 e geoipupdate, e foram acrescentados um exemplo de restrição do painel do WordPress e um aviso sobre CDN). Este artigo é mantido pela WordPress Hakase (Lightscend Co., Ltd.).

Dúvidas sobre WordPress? Quem publica este site fica no Japão e responde em japonês. Contato (em japonês)

お気軽にご相談ください

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