Bloquear dinamicamente IPs que fingem ser Googlebots maliciosos através de busca reversa com fail2ban

7 min

language: ja bn en es hi pt ru zh-cn zh-tw

Olá, aqui é o Munou.
Anteriormente
Investigação de IPs de requisição que se dizem bots do Google, incluindo abusos - SOULMINIGRIG

Aqui, confirmei que existe um número considerável de grupos de IPs que fazem requisições fingindo ser o Google.
Mas como bloqueá-los? Em outras palavras, seria ideal se o fail2ban pudesse detectá-los e executar um script específico, e encontrei uma dica na seguinte issue.
apache-fakegooglebot: whitelist · Issue #1318 · fail2ban/fail2ban · GitHub

Para simplificar, capturamos os bots do Google de forma ampla e, em seguida, realizamos a verificação de ignoreip com um script específico.
Isso deve funcionar.

jail.local

Adicione o seguinte.


[fake-googlebot]
enabled = true
filter = fake-googlebot
port = http,https
logpath = /var/log/nginx/access.log
findtime = 1w
maxretry = 1
bantime = 99999w
ignorecommand = /usr/local/bin/check_googlebot.sh <ip>
action = pf[name=fake-googlebot]

Neste caso, é necessário criar o fake-googlebot como condição de filtro.
Além disso, o script shell configurado em ignorecommand também é necessário.

filter.d/fake-googlebot.conf

Capturamos de forma ampla da seguinte maneira.

[Definition]
failregex = ^<HOST> - .*"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) .*" \d+ \d+ ".*" ".*Googlebot.*"$
ignoreregex =

/usr/local/bin/check_googlebot.sh

No caso do ignorecommand, ele é tratado como alvo de banimento ao receber um código de status de falha durante a execução.
Ou seja, ao passar o endereço IP como argumento e receber o código de status da execução, é possível determinar se deve ser banido ou ignorado.

#!/bin/sh
IP="$1"
LOG="/var/log/check_googlebot.log"
# DNS reverso
HOST=$(getent hosts "$IP" | awk '{print $2}' | head -n1)
if [ -z "$HOST" ]; then
  echo "[$(date)] DENY $IP: no PTR" >> "$LOG"
  exit 1
fi
# Verificar se é um domínio do Google
case "$HOST" in
  *.googlebot.com|*.google.com)
    ;;
  *)
    echo "[$(date)] DENY $IP: invalid domain ($HOST)" >> "$LOG"
    exit 1
    ;;
esac
# DNS direto para verificar se coincide com o IP original
MATCH=1
getent hosts "$HOST" | awk '{print $1}' | while read -r RESOLVED; do
  if [ "$RESOLVED" = "$IP" ]; then
    MATCH=0
    break
  fi
done
if getent hosts "$HOST" | awk '{print $1}' | grep -Fxq "$IP"; then
  echo "[$(date)] ALLOW $IP: valid Googlebot ($HOST)" >> "$LOG"
  exit 0
else
  echo "[$(date)] DENY $IP: mismatch ($HOST)" >> "$LOG"
  exit 1
fi

O motivo de não usar o comando host é que ele não é um comando universal. Em sistemas baseados em Debian, parece estar incluído no bind-utils, mas obtemos o registro PTR através do getent hosts, que está disponível se o glibc estiver instalado.
[SOLVED] Host command / Newbie Corner / Arch Linux Forums

Verificação

Tente executar e verifique se o IP do bot do Google retorna 0.

# sh /usr/local/bin/check_googlebot.sh 66.249.74.78
# echo $?
0

E se for um IP diferente? Vamos tentar inserir o IP do meu próprio servidor.

# sh /usr/local/bin/check_googlebot.sh 163.44.113.145
# echo $?
1

Parece estar funcionando corretamente.

fail2ban

Reinicie para aplicar este filtro no fail2ban.

service fail2ban restart
fail2ban-client status 

Verifique abaixo se os IPs recentes do Google não foram banidos por engano.

# fail2ban-client status fake-googlebot
Status for the jail: fake-googlebot
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/nginx/access.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

Alguns logs da execução com o IP do meu próprio servidor logo antes permaneceram, mas os bots do Google parecem estar sendo identificados corretamente nos logs.

# tail /var/log/check_googlebot.log 
[Sun Apr 19 01:58:18 JST 2026] ALLOW 66.249.74.65: valid Googlebot (crawl-66-249-74-65.googlebot.com)
[Sun Apr 19 01:58:18 JST 2026] ALLOW 66.249.74.78: valid Googlebot (crawl-66-249-74-78.googlebot.com)
[Sun Apr 19 01:58:18 JST 2026] ALLOW 66.249.74.64: valid Googlebot (crawl-66-249-74-64.googlebot.com)
[Sun Apr 19 01:58:18 JST 2026] ALLOW 66.249.74.64: valid Googlebot (crawl-66-249-74-64.googlebot.com)
[Sun Apr 19 01:58:19 JST 2026] ALLOW 66.249.74.64: valid Googlebot (crawl-66-249-74-64.googlebot.com)[Sun Apr 19 01:58:19 JST 2026] ALLOW 66.249.74.78: valid Googlebot (crawl-66-249-74-78.googlebot.com)
[Sun Apr 19 01:58:19 JST 2026] ALLOW 66.249.74.64: valid Googlebot (crawl-66-249-74-64.googlebot.com)
[Sun Apr 19 01:58:19 JST 2026] ALLOW 66.249.74.78: valid Googlebot (crawl-66-249-74-78.googlebot.com)
[Sun Apr 19 03:56:30 JST 2026] ALLOW 66.249.74.78: valid Googlebot (crawl-66-249-74-78.googlebot.com)
[Sun Apr 19 03:58:18 JST 2026] DENY 163.44.113.145: invalid domain (v163-44-113-145.v1i0.static.cnode.jp)

No entanto, neste caso, como uma consulta de registro PTR seria realizada a cada solicitação do Googlebot, seria recomendável implementar algo como um pseudo-cache, permitindo IPs que já constam como ALLOW sem realizar uma nova consulta.

Related Posts