玩命狂奔的间隙,莫忘记抬头看看前路的星光

0%

网站最近被垃圾流量爆刷:使用Nginx 反爬虫和防恶意流量

问题发现

周一早上照例查看服务器监控,发现上周末的流量曲线异常陡峭。进入百度统计后台,发现了大量来自 web3000.ioshouiang.ioganda.io 等域名的访问记录,访问路径都是类似 /qdd2000 这样的特征 URL。

翻看 Nginx 日志,情况更明显:

1
2
3
58.51.151.234 - - [12/Dec/2025:17:37:26 +0800] "GET / HTTP/1.1" 200 5432 "https://web3000.io/qdd2000" "Mozilla/5.0..."
27.158.126.157 - - [12/Dec/2025:17:31:16 +0800] "GET / HTTP/1.1" 200 5432 "https://shouiang.io/qdd2000" "Mozilla/5.0..."
101.204.100.242 - - [12/Dec/2025:17:50:40 +0800] "GET / HTTP/1.1" 200 5432 "https://ganda.io/qdd2000" "Mozilla/5.0..."

这些请求的特征是:都带着这些垃圾站点的 Referer,访问我的首页,然后就没有然后了。显然是某种 SEO 作弊或者流量劫持手段。

问题是这些 IP 分布在不同的地区和运营商,显然背后有个 IP 池。单纯封 IP 没有意义。

技术方案选择

既然 IP 封不住,那就从请求特征入手。这些垃圾请求最明显的共同点就是 Referer 字段。

Nginx 的 map 模块可以根据请求头创建变量,配合 if 指令可以实现基于规则的拦截。虽然 Nginx 官方文档里反复强调”if is evil”,但在这种简单的拦截场景下,if 配合 return 是最直接的方案。

考虑到我的服务器上跑着多个站点,最好能做到一次配置、全局生效。所以方案是:

  1. http 块定义 map,标记垃圾 Referer
  2. 在每个 server 块应用拦截逻辑

配置实现

定义检测规则

/etc/nginx/nginx.confhttp 块中添加:

1
2
3
4
5
6
7
8
9
10
11
12
http {
map $http_referer $is_spam_referer {
default 0;
"~*web3000\.io" 1;
"~*qdd2000" 1;
"~*shouiang\.io" 1;
"~*ganda\.io" 1;
}

# 其他配置...
include /etc/nginx/vhost/*.conf;
}

map 的工作原理是模式匹配。~* 表示不区分大小写的正则匹配。当 $http_referer 匹配任意一条规则时,$is_spam_referer 被设为 1,否则为 0。

这里同时匹配了域名(web3000.io)和路径特征(qdd2000),覆盖面更广。

应用拦截规则

我的站点配置使用了 Certbot,所以有 HTTP 和 HTTPS 两个 server 块。垃圾流量往往先访问 HTTP,所以两个地方都要加拦截:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
server_name example.com www.example.com;

if ($is_spam_referer = 1) {
return 444;
}

return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com www.example.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

if ($is_spam_referer = 1) {
return 444;
}

location / {
# 业务逻辑
}
}

这里用 return 444 而不是 return 403。444 是 Nginx 的非标准状态码,效果是直接关闭连接,不发送任何响应。相比 403 还要返回错误页面,444 更节省带宽和处理时间。

需要注意的是,拦截要放在重定向之前。如果垃圾请求先被重定向到 HTTPS,依然会消耗 HTTP 层的资源。

补充限流策略

除了特征拦截,还需要防范新出现的垃圾源。添加基于 IP 的限流:

1
2
3
4
5
6
http {
# 之前的 map 定义...

limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}

然后在 server 块中应用:

1
2
limit_req zone=global_limit burst=20 nodelay;
limit_conn conn_limit 10;

limit_req_zone 定义了一个共享内存区域 global_limit,大小 10MB,可以存储约 16 万个 IP 的状态信息。rate=10r/s 表示每秒 10 个请求的平均速率。

limit_req 应用这个限制时,burst=20 允许突发流量,即短时间内超过 10 req/s,但最多积压 20 个请求。nodelay 表示超出限制立即返回 503,不排队等待。

limit_conn 限制单个 IP 的并发连接数为 10。这对于防范慢速攻击(建立连接但不发数据)很有效。

测试验证

配置后先检查语法:

1
nginx -t

没问题就重载:

1
nginx -s reload

用 curl 模拟垃圾请求测试拦截效果:

1
curl -I -H "Referer: https://web3000.io/qdd2000" http://example.com

如果配置生效,会看到:

1
curl: (52) Empty reply from server

这就是 444 状态码的效果——连接被服务器主动关闭,连 HTTP 响应头都不返回。

测试正常访问:

1
curl -I http://example.com

应该返回 301 重定向到 HTTPS。

效果监控

实时查看被拦截的请求:

1
tail -f /var/log/nginx/access.log | grep " 444 "

统计被拦截的垃圾 Referer 分布:

1
grep " 444 " /var/log/nginx/access.log | grep -oP '"https?://[^"]+' | sort | uniq -c | sort -rn

部署后观察了一周,日志中 444 状态码的记录明显增多,服务器负载下降,百度统计里的垃圾访问数据也减少了。

技术细节解析

为什么不用 IP 黑名单

很多人第一反应是封 IP,但这对抗 IP 池效率太低。况且很多垃圾流量来自普通家庭宽带的肉鸡,这些 IP 明天可能就是正常用户。

基于行为特征(Referer)拦截更精准,误杀率低。在 Web 服务器防护、网站安全防御、反爬虫策略中,特征匹配往往比 IP 封禁更有效。

关于 if 指令的争议

Nginx 官方文档和社区都在说”if is evil”,主要是因为 iflocation 块中的行为不符合直觉,容易出现配置错误。但在 server 块中用 if 配合 return 做简单判断是安全的。

如果真的担心,可以用 geomap 配合 try_files 实现,但那样 Nginx 配置会复杂很多。对于网站运维、服务器管理来说,简单可靠的方案往往是最好的。

限流参数的选择

rate=10r/sburst=20 是根据我的站点实际情况定的。个人博客的访问模式通常是:用户打开页面,浏览器并发请求 HTML、CSS、JS、图片等资源。一次访问可能触发十几个请求,但集中在 1-2 秒内。

所以 10 req/s 的平均速率配合 20 的 burst 值,既能允许正常用户的突发请求,又能拦截恶意的高频访问。这是典型的请求频率限制、并发连接限制、流量控制策略。

如果站点类型不同(比如 API 服务、电商网站、内容管理系统),需要根据实际情况调整。

Nginx 日志分析的重要性

这次问题的发现就是通过服务器监控和日志分析。服务器监控只能告诉你”流量异常”,但具体是什么问题,必须靠 access.log 和 error.log 分析。

定期查看 Nginx 访问日志,统计 User-Agent、Referer、状态码分布,能提前发现很多问题。这也是 Web 服务器运维、网站性能优化、安全防护的基本功。

后续优化方向

目前的方案是静态规则,需要手动更新。后续可以考虑:

  1. 用 Shell 脚本或 Python 脚本定期分析日志,自动提取新的垃圾 Referer 特征,更新 Nginx 配置并 reload
  2. 接入 fail2ban,自动封禁触发限流的 IP(临时封禁,比如 1 小时),实现动态防御
  3. 如果垃圾流量继续增长,考虑接入 Cloudflare、腾讯云 CDN、阿里云 CDN 之类的服务,利用它们的 WAF(Web Application Firewall)和 Bot Management 功能
  4. 部署 ModSecurity 或 Naxsi 这样的 Web 应用防火墙模块
  5. 使用 GeoIP 模块进行地理位置过滤,如果业务只面向特定地区

但就目前的情况,这套基于 Nginx map 指令和 limit_req 模块的配置已经够用了。

配置文件位置

最后梳理一下配置文件的组织方式。我的服务器上 Nginx 配置是这样的:

1
2
3
4
5
6
/etc/nginx/
├── nginx.conf # 主配置,http 块在这里
├── vhost/
│ ├── site1.conf # 各个站点的 server 块
│ ├── site2.conf
│ └── ...

maplimit_req_zone 定义在 nginx.confhttp 块中,所有站点共享。

每个站点的 server 块在独立的配置文件里,通过 include vhost/*.conf; 加载。

这样的好处是:

  • 添加新站点时,只需在 vhost/ 目录新建配置文件
  • 全局规则(如垃圾 Referer 列表)统一维护
  • 每个站点的配置互不干扰

这种配置结构对于 Linux 服务器管理、虚拟主机配置、多站点部署来说非常实用。

攻击者的真实动机分析

经过这次事件,我一直在思考:这些垃圾流量背后的人到底想干什么?

Referer Spam 的商业模式

仔细研究了这些域名(web3000.io、shouiang.io、ganda.io)的内容,发现它们都是一些灰色产业网站。这种攻击手段叫做 Referer Spam(引荐来源垃圾信息),它的商业逻辑是这样的:

  1. 利用站长的好奇心:大多数网站管理员会定期查看流量统计,看到大量来自某个陌生域名的访问,第一反应往往是好奇”这是什么网站?为什么会给我带来这么多流量?”于是就会点击进去看看。

  2. SEO 权重提升:一些老旧的统计工具(比如早期的 Google Analytics、百度统计)会公开展示 Referer 数据。爬虫可以爬取这些公开数据页面,这样垃圾网站的 URL 就出现在了成千上万个网站的公开页面上,形成了大量的外链。虽然这些外链的质量很低,但在某些搜索引擎的算法中,仍然能带来一定的 SEO 收益。

  3. 刷虚假流量:某些广告联盟或流量交易平台会根据 Referer 数据来计费。攻击者通过伪造 Referer,可以制造”从他们网站跳转过来的用户”的假象,从而获得广告分成或流量费用。

  4. 建立流量池:这些垃圾站通常会在页面上植入大量广告、弹窗,甚至恶意代码。只要有一小部分站长因为好奇点击进去,就能产生广告收入。按照互联网营销的转化率来算,哪怕只有 0.1% 的人点击,在海量请求的基数下,收益也是可观的。

为什么选择我的网站

从技术角度分析,这些攻击者并不是针对我的网站,而是批量扫描互联网上所有可访问的网站。他们的目标是:

  • 有公开流量统计工具的网站(百度统计、Google Analytics、CNZZ 等)
  • 有一定访问量的网站(说明站长会关注数据)
  • 服务器响应正常的网站(返回 200 状态码)

我的博客只是恰好在他们的扫描范围内。这种攻击的成本极低:租一批云服务器或肉鸡,写个简单的 HTTP 请求脚本,就能对全网进行地毯式轰炸。

产业链的规模

这不是个例。通过搜索 “web3000.io referer spam”、”shouiang.io 垃圾流量”、”qdd2000 恶意访问” 等关键词,能找到大量站长的投诉和讨论。国内外的技术论坛、站长论坛、运维社区里,每天都有人在问”为什么我的网站流量统计里出现这些奇怪的域名”。

这说明背后是一个有组织的、规模化的产业链。他们可能在运营数百个这样的垃圾站,每天向全球数百万个网站发送垃圾请求。只要有千分之一的转化率,就足以支撑起这门生意。

更有甚者,这些域名背后可能还涉及更深层的问题:

  • 恶意软件分发:有些垃圾站会诱导用户下载”工具软件”,实际是木马或广告插件
  • 钓鱼网站:伪装成合法服务,骗取用户的账号密码或支付信息
  • 挖矿脚本:在用户浏览时偷偷调用浏览器算力挖掘加密货币
  • DDoS 肉鸡招募:感染用户设备,加入僵尸网络

我们能做什么

作为个人站长或运维人员,除了技术层面的防御(本文介绍的 Nginx 配置),还应该:

  1. 不要好奇点击垃圾 Referer:这正中攻击者下怀,给他们带来真实流量
  2. 关闭统计工具的公开访问:百度统计、Google Analytics 等工具的数据页面应该设为私密
  3. 定期更新防御规则:垃圾网站的域名会不断变化,要持续监控日志并更新黑名单
  4. 使用 HTTPS 和 HSTS:强制 HTTPS 可以减少中间人劫持和流量劫持
  5. 举报滥用域名:向域名注册商(如 GoDaddy、Namecheap)和托管服务商举报这些恶意域名

从产业角度看,这类攻击很难彻底根除。只要互联网上还有流量统计工具、还有好奇的站长、还有广告联盟的利益驱动,Referer Spam 就会持续存在。我们能做的,就是提高自己的防御能力,不成为攻击链条中的受害者或帮凶。

总结

这次处理垃圾流量的过程,本质上是在做特征识别和规则匹配。技术方案很简单,但关键在于理解问题的本质:这些流量想干什么、有什么共同特征、如何用最小的代价拦截它们。

Web 服务的攻防、网络安全防护、反爬虫技术,很多时候就是这样。面对 Referer Spam、恶意爬虫、DDoS 攻击这些威胁,运维工程师需要掌握 Nginx 防火墙配置、服务器安全加固、日志分析技巧、流量监控方案。

而当我们深入分析攻击者的动机和产业链运作模式,会发现互联网安全不仅是技术问题,更是经济利益和人性博弈的战场。


相关技术关键词:Nginx 反爬虫、Web 服务器防护、Referer Spam 拦截、限流配置、map 指令、网站安全、恶意流量过滤、SEO 作弊防御、服务器运维、访问日志分析、HTTP 状态码 444、fail2ban、WAF 配置、IP 黑名单、请求频率限制、并发连接控制、Nginx 配置优化

适用场景:个人博客、企业网站、API 服务、内容管理系统、电商平台、在线服务