一、问题
我用一个简单的陷阱就将网站的机器人流量减少了 80% 以上。
上个月,我的业余网站向访客传输了超过 2.5TB 的数据。虽然我很希望这个网站非常受欢迎,但看起来更像是 AI 机器人不停地抓取数据和下载图片。
所以我打造成一款不加区分、彻底清除这些不受欢迎的寄生虫的工具。
它的灵感很大程度上来源于Jeff Starr 的 Blackhole,但即使在缓存严重的网站上也能正常工作。
以下是对其工作原理的简要描述。
/honeypot/ 在您的网站上 创建一个类似目录。
index.php 在目录中 放入一些代码。
将蜜罐添加为明确的“禁止”项。 robots.txt
在网站的每个页面上添加指向蜜罐的隐藏链接。
如果有任何东西访问该页面,请将其 IP 地址写入您的 .htaccess
这 .htaccess 会彻底禁止该IP地址再次访问您的网站。
这篇博文将向您展示如何自行构建此功能,并讨论它可能引起的一些问题。
二、解决
robots.txt 文件位于网站根目录。它包含一系列指令,用于指导自动网络爬虫抓取网站内容。负责任的爬虫会读取此文件,并拒绝抓取网站的特定部分。
添加以下两行:
User-agent: *
Disallow: /honeypot/
也就是说,机器人不应该访问蜜罐目录中的任何页面。
机器人通常每 24 小时检查一次更新,所以要么等一天,要么手动将其提交给主要爬虫。
.htaccess 文件包含服务器处理请求的指令列表。
.htaccess找到文件中类似这样的部分:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
修改后的样子如下:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
### BLOCKED IPs
# TEST-NET-1
RewriteCond %{REMOTE_ADDR} "=192.0.2.1"
RewriteRule ^ - [R=402,L]
### /BLOCKED IPs
重要的是,这些规则必须先于任何其他重写规则。
将结尾部分修改 IfModule 成这样:
</IfModule>
ErrorDocument 402 "Payment Required - Access Denied."
如果某个 IP 地址在被屏蔽的 IP 列表中,服务器将发送错误代码和一条可读消息。您可以在此处添加任何您想要的纯文本。
在蜜罐目录下,创建一个名为index.php(或其他你喜欢的名称)的文件。当访客访问此页面时,它会抓取访客的 IP 地址及其用户代理名称,然后将其添加到“已阻止的 IP 地址”部分。
// What's their IP?
$IP = get_client_ip();
// User Agent
$UA = isset( $_SERVER["HTTP_USER_AGENT"] ) ? $_SERVER["HTTP_USER_AGENT"] : "";
// Get the existing .htaccess file.
$htaccess_file = "../.htaccess";
$htaccess = file_get_contents( $htaccess_file );
// Split by newline.
$htaccess_lines = explode( separator: "\n", string: $htaccess );
// Where's our start block?
$start = "### BLOCKED IPs";
$end = "### /BLOCKED IPs";
// Exit if the .htaccess doesn't have the block.
if ( !in_array( needle: $start, haystack: $htaccess_lines ) ) { die(); }
// This is where to start from.
$start_block = array_search( needle: $start, haystack: $htaccess_lines );
// Add the line after the start block.
// Include a date.
$htaccess_lines[ $start_block ] = $start . "\n" .
"\t#\t" . date( "c" ) . "\t{$UA}\n" .
"\tRewriteCond %{REMOTE_ADDR} \"={$IP}\" [OR]";
// Turn the array back to a string.
$newHtaccess = implode( separator: "\n", array: $htaccess_lines );
// Save the new .htaccess file.
file_put_contents( filename: $htaccess_file, data: $newHtaccess );
function get_client_ip():string
{
// Adapted from https://github.com/ibericode/koko-analytics/blob/main/src/Resources/functions/collect.php
// X-Forwarded-For sometimes contains a comma-separated list of IP addresses
// @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
$ips = empty( $_SERVER["HTTP_X_FORWARDED_FOR"] ) ?
[] :
\array_map( "trim", \explode( ",", $_SERVER["HTTP_X_FORWARDED_FOR"] ) );
// Always add REMOTE_ADDR and HTTP_CLIENT_IP to list of ip addresses, if set
foreach ( ["REMOTE_ADDR", "HTTP_CLIENT_IP"] as $key ) {
if ( !empty( $_SERVER[$key] ) ) {
$ips[] = $_SERVER[$key];
}
}
// Return first valid IP address from list
foreach ( $ips as $ip ) {
if ( \filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
return $ip;
}
}
return "";
}
网络爬虫会抓取网页,找到网页上的所有链接,然后访问这些链接。因此,我们需要在每个页面上放置一个指向蜜罐的链接——但要确保普通用户无法找到或点击它。
这会添加一个链接,将其从辅助功能树中移除,并使其无法点击(零宽度连接符)。
<a id="honey" aria-hidden="true" href="/honeypot/index.php"></a>
这段 CSS 代码会将其对普通用户隐藏,并移除鼠标光标。
#honey {
display: none !important;
cursor: none !important;
}
这可能导致的问题
不太可能有人会找到这个链接,点击后被封禁。但如果真有人这么做了,可以考虑在封禁信息中添加一条消息,告诉他们如何解除封禁。
有些有用的机器人会忽略 robots.txt 文件。如果它们通过 User-Agent 字符串表明身份(它们应该这样做),您可以手动从 .htaccess 文件中移除它们。您也可以为它们添加允许列表的例外规则。当然,很多恶意机器人会伪装自己的真实身份。
反之,并非所有机器人都会抓取每个链接。因此,这种方法无法检测到那些遵守 robots.txt 规则但仍然造成问题的机器人。
如果你屏蔽了成千上万个不同的机器人,解析 .htaccess 文件时服务器性能可能会下降。虽然有一些零星的证据表明这会增加一些额外的开销,但我个人认为这无需担心。
机器人程序通常会使用被劫持的IP地址。机器人程序转移后,无辜的用户可能会被您的网站屏蔽。每次屏蔽都会记录时间戳。您可以定期解除对较早记录的屏蔽。
机器人会轮换使用数百个不同的IP地址。因此,同一个机器人可能会被多次封禁。
机器人可能会将 CSS 代码标记为隐藏链接,从而拒绝访问。除了使用 CSS 代码,您还可以使用不可见的空格或其他人类难以识别但机器人可见的字符。
同样,一个智能机器人可能会拒绝访问名为 /honeypot/ 的路径,因此会为其选择一个更好的名称。更智能的机器人会意识到触碰蜜罐会导致封禁——所以或许需要设置一系列陷阱?
顾名思义,这是一种直接封禁的手段。它不会发出警告,也不会查看用户代理、国家/地区或任何其他信息。一旦触碰到这个“蜜罐”,就会立即被封禁。没有警告,也没有任何自动申诉途径。
替代方案
还有其他方法可以做到这一点。有些机器人不会发送语言标头,有些使用旧版本的HTTP协议,它们的User Agent字符串通常严重过时。这些都是阻止疑似机器人的合理方法。不过,也可能会出现一些误报。
但没有误报。正常用户不会点击该链接进入陷阱,行为良好的机器人也不会点击该链接。
我并不声称这是目前最先进的机器人拦截器——但我很享受自己开发它的过程。我可能会添加记录 IP 地址地理位置的功能,并可能移除超过一定时间的拦截记录。
原文链接
https://shkspr.mobi/blog/2026/11/blunt-banhammer-blocks-basic-bots-ballistically/#bad-robots