使用 fail2ban 通过反向解析动态拦截伪装成 Googlebot 的恶意 IP
你好,我是无能。
上次
调查自称来自 Google bot 的请求 IP(包括滥用情况) - SOULMINIGRIG
在这里,我确认了确实存在相当一部分伪装成 Google 发送请求的 IP 组。
但是如何拦截它们呢?也就是说,只要能在 fail2ban 侧检测到并运行指定的脚本即可,我在以下 issue 中找到了提示:
apache-fakegooglebot: whitelist · Issue #1318 · fail2ban/fail2ban · GitHub
简单来说,就是先大范围匹配 Google 的 Bot,然后通过指定的脚本进行 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 中设置的 Shell 脚本。
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 地址作为参数传递并接收执行时的状态码,就可以判定是进行封禁还是将其作为跳过对象。
#!/bin/sh
IP="$1"
LOG="/var/log/check_googlebot.log"
# 反向解析
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 中,但只要安装了 glibc,就可以通过 getent hosts 获取 PTR 记录。
[SOLVED] Host command / Newbie Corner / Arch Linux Forums
验证
尝试执行一下,确认 Google Bot 的 IP 返回值为 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 的 IP。
# 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 的 bot 判定似乎是正常的。
# 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)