MG DEV

Proteja seu site/loja e reduza custos de tráfego de forma fácil com Nginx e Geoip2 e uma lista de ASN

A lógica: Quantos usuários legítimos ou clientes acessam seu site/loja utilizando um IP de uma empresa de hospedagem? Provavelmente nenhum, pois a maioria estarão utilizando um IP disponibilizado por um ISP. Já os acessos maliciosos são feitos em sua maior parte de IPs de empresas de hospedagem, em um caso específico de uma loja que administro, 95% das solicitações maliciosas vem de empresas de hospedagens usadas por hackers.

Em uma das lojas que administro hoje foram bloqueados aproximadamente 80 mil solicitações em uma loja que tem apenas 60 mil acessos legítimos no mês. Grande parte dessas solicitações podem resultar em solicitações em nos arquivos estáticos da página, por exemplo, se o site tem 100 arquivos estáticos (css, js, imagens), poderíamos multiplicar 80.000 x 100 = 8.000.000.

Quando você usa serviços como AWS e CDNs, no caso ainda temos o Argo ativado no CloudFlare, essas 8 milhões de solicitações reduz o custo consideravelmente e não só isso, você ainda se protege de vários tipos de ataques, economiza recursos de CPU e Memoria do servidor o que pode em alguns casos até melhorar a velocidade do site:

Atualmente o bloqueio por IP não é o suficiente, então podemos ir mais fundo e ver qual é a ASN deste IP (ID da empresa que detém o IP). Normalmente este ID é vinculado á um bloco de IP que na maioria das vezes a lista pode ser enorme. Mas fique atento, o recomendado é bloquear apenas  empresas de hospedagens, e não bloquear os ISPs.

Como consultar um ASN? Existem centenas de ferramentas online de informações de IP que exibe o código ASN, por exemplo https://ipinfo.io/.

Riscos: Ao bloquear os ASNs da Amazon você irá bloquear apis que estão hospedadas la como por exeplo o Bling. Você também precisa estar atento aos bots como Google, Facebook, Pinterest, etc. Nestes casos é preciso uma configuração adicional e todo o resto de empresas de hospedagens podem ser bloqueados sem problemas.

O bloqueio pode ser feito no CDN (se suportar), no caso da Cloudflare e diretamente no NGINX e eu irei explicar como fazer logo abaixo. Caso tenha alguma dúvida ou sugestão é só postar nos comentários.

Bloqueando no servidor.

Exemplo de configuração em um servidor Linux Ubuntu com Nginx e geoip2:

1 – Instalar as dependências e baixar o ngx_http_geoip2_module. Estou supondo que será baixado no diretório /home/ubuntu e você já sabe compilar o nginx, caso não saiba, logo irei postar uma compilação otimizada para o Nginx passo a passo.

apt-get install libgeoip-dev git
cd /home/ubimti
git clone https://github.com/leev/ngx_http_geoip2_module
sudo add-apt-repository ppa:maxmind/ppa
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin

2  – Compilar o Nginx (Funciona também no Tengine), adicionando essa opção no ./configure –add-module=/home/ubuntu/ngx_http_geoip2_module.

3 – No lugar de $realip você pode usar $http_x_forwarded_for ou $remote_addr porém se você tem um CDN, o IP real virá de $http_x_forwarded_for mas pode acontecer de receber solicitações diretamente no servidor sem passar pelo CDN e então o cabeçalho $http_x_forwarded_for estará vazio. Este é uma solução simples para o problema.
Adicionar os blocos de opções em /etc/nginx/nginx.conf no escopo http.

#Solução para $http_x_forwarded_for vazio.
map $http_x_forwarded_for $realip {
~^(\d+\.\d+\.\d+\.\d+) $1;
default $remote_addr;
}

geoip2 /etc/nginx/GeoLite2-ASN.mmdb {
auto_reload 60m;
# Nome da empresa, ex: Google Inc.
$geoip2_data_org source=$realip autonomous_system_organization;
# código asn, ex: 2569
$geoip2_data_asn source=$realip autonomous_system_number;
}

4 – Configurar um log personalizado para mostrar $geoip2_data_asn e $geoip2_data_org nas informações de acessos. Se você usa Dadadog Log, você pode configurar assim por exemplo:

log_format json_combined escape=json
'{'
'"http.version":"$server_protocol",'
'"http.status_code":$status,'
'"http.method":"$request_method",'
'"http.referer":"$http_referer",'
'"http.useragent":"$http_user_agent",'
'"http.url":"$request_uri",'
'"date":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"body_bytes_sent":"$body_bytes_sent",'
'"duration":$request_time,'
'"response_content_type":"$sent_http_content_type",'
'"X-Forwarded-For":"$http_x_forwarded_for",'
'"network.client.geoip.country.iso_code":"$geoip2_data_country_code",'
'"ssl_protocol":"$ssl_protocol",'
'"http.host":"$http_host",'
'"asn":"$geoip2_data_asn",'
'"asn_org":"$geoip2_data_org",'
'"realip":"$realip",'
'}';

5 – adicionar o log nos locais desejados, exemplo, no bloco server, http ou location: access_log /var/log/nginx/acessos_json.log json_combined buffer=256k flush=10s;
As opções adicionais “buffer=256k flush=10s” é para evitar escritas e leituras excessivas no disco. Você pode saber mais na documentação do Nginx.

6 – Monitorar e bloquear. Neste momento temos o log de acesso com o código ASN para fazer o monitoramento, o próximo passo é fazer o bloqueio. Recomendo utilizar um serviço de monitoramento de logs para facilitar, exemplo Datadog, irei criar um outro post explicando isso no futuro.

Aqui eu mantenho uma lista com os que estão bloqueados: https://github.com/redati/magento2-ubuntu-dep/blob/main/nginx/security/bad_asn.conf

Para melhor organização, crie um arquivo, por exemplo /etc/nginx/bad_asn e então faça a inclusão em nginx.conf no escopo http: include /etc/nginx/bad_asn

No arquivo bad_asn você irá manter atualizado a lista que será bloqueada da seguinte forma:

map $geoip2_data_asn $bad_asn {

#padrão 0 permitido
default 0;
#exemplo, para bloquear, deixe com o valor 1.
"923" 1;
#exemplo 2
"333" 1;
#etc...
}

Por fim adicione no local que deseja fazer o bloqueio: { if ($bad_asn) { return 403; } }

Pronto, agora temos nosso Nginx um pouco mais protegido. Se você conhece uma forma de integrar GeoIp2 com Naxsi, compartilhe conosco.

Bloqueando com CloudFlare e outros serviços que dão suporte para ASN.

A configuração é bem simples, no menu Firewall é possível adicionar o código ASN, porém é preciso adicionar o as letras “AS” + código, exemplo “AS5588” e então você pode escolher a ação, bloqueio, desafio ou permitir.

Outras considerações importantes.

1 – Não redirecione acessos em seu IP para seu site. O motivo é simples, quem acessa seu site diretamente pelo ip do servidor? Ninguém e muito provavelmente são acessos maliciosos.
2 – Se seu site é totalmente SSL você não deveria redirecionar todos os acessos da porta 80 para 443 porque conexões ssl requerem maior uso de CPU e você já pode criar algumas regras de bloqueio antes de retornar o redirecionamento, por exemplo:

server {

listen 80 default_server;
listen [::]:80 ipv6only=on default_server;

if ($bad_asn) { return 403; }
#"user agent" vazio.
if ($http_user_agent = '') { return 403; }
#acesso diretamente via IP
If ($host = 'IP DO SERVIDOR'){ return 403; }
#conexões diferente do mêtodo GET.
if ($request_method !~ ^(GET)$ ){ return 403; }

rewrite_log off;
access_log off;
return 301 https://$http_host$request_uri;

}