Bloquear dinámicamente con fail2ban las IPs que suplantan a Googlebot mediante búsqueda inversa
Hola, soy Munou.
Anteriormente
Investigación de IPs de solicitudes que dicen ser bots de Google, incluyendo abusos - SOULMINIGRIG
Aquí confirmé que hay bastantes grupos de IPs que realizan solicitudes haciéndose pasar por Google.
¿Pero cómo bloquearlos? En otras palabras, sería ideal si fail2ban pudiera detectarlos y ejecutar un script específico, y encontré una pista en el siguiente issue.
apache-fakegooglebot: whitelist · Issue #1318 · fail2ban/fail2ban · GitHub
En términos sencillos, capturamos los bots de Google de forma amplia y luego realizamos la determinación de ignoreip con un script específico.
Esto debería funcionar.
jail.local
Añade lo siguiente.
[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]
En este caso, es necesario crear fake-googlebot como condición de filtro.
Además, se requiere el script de shell configurado en ignorecommand.
filter.d/fake-googlebot.conf
Captura de forma amplia de la siguiente manera.
[Definition]
failregex = ^<HOST> - .*"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) .*" \d+ \d+ ".*" ".*Googlebot.*"$
ignoreregex =
/usr/local/bin/check_googlebot.sh
En el caso de ignorecommand, se maneja como un objetivo de baneo al recibir un código de estado de fallo durante la ejecución.
Es decir, al pasar la dirección IP como argumento y recibir el código de estado de su ejecución, se puede determinar si es un baneo o si debe ser omitido.
#!/bin/sh
IP="$1"
LOG="/var/log/check_googlebot.log"
# Búsqueda inversa (Reverse DNS)
HOST=$(getent hosts "$IP" | awk '{print $2}' | head -n1)
if [ -z "$HOST" ]; then
echo "[$(date)] DENY $IP: no PTR" >> "$LOG"
exit 1
fi
# Verificar si es un dominio de Google
case "$HOST" in
*.googlebot.com|*.google.com)
;;
*)
echo "[$(date)] DENY $IP: invalid domain ($HOST)" >> "$LOG"
exit 1
;;
esac
# Realizar búsqueda directa y verificar si coincide con la 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
La razón por la que no utilizo el comando host es porque no es un comando universal. En sistemas basados en Debian parece estar incluido en bind-utils, pero obtengo el registro PTR desde getent hosts, que está disponible si glibc está instalado.
[SOLVED] Host command / Newbie Corner / Arch Linux Forums
Confirmación
Prueba a ejecutarlo y confirma que devuelve 0 con una IP de un bot de Google.
# sh /usr/local/bin/check_googlebot.sh 66.249.74.78
# echo $?
0
¿Y qué pasa con una IP diferente? Intentemos con la IP de mi propio servidor.
# sh /usr/local/bin/check_googlebot.sh 163.44.113.145
# echo $?
1
Parece que la determinación funciona correctamente.
fail2ban
Reinicia para aplicar este filtro en el lado de fail2ban.
service fail2ban restart
fail2ban-client status
Verifica a continuación que las IPs recientes de Google no hayan sido baneadas por error.
# 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:
Quedaron algunos registros de cuando ejecuté la prueba con la IP de mi propio servidor justo antes, pero en los logs parece que los bots de Google se están determinando correctamente.
# 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)
Sin embargo, en este caso, dado que se realizaría una consulta de registro PTR cada vez que haya una solicitud de Googlebot, sería mejor implementar algo similar a una pseudo-caché, permitiendo las IPs que ya son ALLOW sin realizar la consulta previa.