Динамическая блокировка IP-адресов, маскирующихся под вредоносных Googlebot, с помощью обратного поиска DNS в fail2ban
Привет, я Munou.
В прошлый раз
Исследование IP-адресов запросов, выдающих себя за ботов Google, включая случаи злоупотребления — SOULMINIGRIG
Здесь я подтвердил, что существует довольно много групп IP-адресов, которые отправляют запросы, маскируясь под Google.
Но как их заблокировать? Другими словами, было бы хорошо, если бы fail2ban мог обнаруживать их и запускать указанный скрипт. Подсказка нашлась в следующем issue:
apache-fakegooglebot: whitelist · Issue #1318 · fail2ban/fail2ban · GitHub
Проще говоря, мы сначала массово отлавливаем всех ботов Google, а затем с помощью специального скрипта выполняем проверку для ignoreip.
Это должно сработать.
jail.local
Добавьте следующее:
[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]
В этом случае необходимо создать фильтр fake-googlebot.
Также потребуется шелл-скрипт, указанный в ignorecommand.
filter.d/fake-googlebot.conf
Настраиваем захват широкого диапазона следующим образом:
[Definition]
failregex = ^<HOST> - .*"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH) .*" \d+ \d+ ".*" ".*Googlebot.*"$
ignoreregex =
/usr/local/bin/check_googlebot.sh
В случае с ignorecommand, если при выполнении возвращается код ошибки, IP-адрес обрабатывается как объект для бана.
То есть, передавая IP-адрес в качестве аргумента и получая код состояния выполнения, можно определить, следует ли забанить адрес или пропустить его.
#!/bin/sh
IP="$1"
LOG="/var/log/check_googlebot.log"
# Обратный поиск (PTR)
HOST=$(getent hosts "$IP" | awk '{print $2}' | head -n1)
if [ -z "$HOST" ]; then
echo "[$(date)] DENY $IP: no PTR" >> "$LOG"
exit 1
fi
# Проверка, принадлежит ли домен Google
case "$HOST" in
*.googlebot.com|*.google.com)
;;
*)
echo "[$(date)] DENY $IP: invalid domain ($HOST)" >> "$LOG"
exit 1
;;
esac
# Прямой поиск для проверки соответствия исходному IP
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
Причина, по которой я не использую команду host, заключается в том, что она не является универсальной. В системах на базе Debian она, кажется, входит в bind-utils, но я получаю PTR-запись через getent hosts, которая доступна, если установлена glibc.
[SOLVED] Host command / Newbie Corner / Arch Linux Forums
Проверка
Попробуем запустить скрипт и убедимся, что для IP-адреса бота Google возвращается 0.
# sh /usr/local/bin/check_googlebot.sh 66.249.74.78
# echo $?
0
А что, если использовать другой IP? Попробую ввести IP своего сервера.
# sh /usr/local/bin/check_googlebot.sh 163.44.113.145
# echo $?
1
Похоже, проверка работает правильно.
fail2ban
Перезапустите fail2ban, чтобы применить этот фильтр.
service fail2ban restart
fail2ban-client status
Проверьте следующее, чтобы убедиться, что недавние IP-адреса Google не были забанены по ошибке.
# 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:
В логах остались записи от проверки IP моего собственного сервера чуть ранее, но боты Google, судя по всему, определяются правильно.
# 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)
Однако в этом случае запрос PTR-записи будет выполняться при каждом обращении Googlebot, поэтому было бы лучше реализовать своего рода псевдо-кэширование, например, разрешать IP-адреса, которые уже имеют статус ALLOW, без повторного выполнения запроса.