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

0%

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

问题发现

周一早上照例查看服务器监控,发现上周末的流量曲线异常陡峭。进入百度统计后台,发现了大量来自 web3000.io、shouiang.io、ganda.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.conf 的 http 块中添加:

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”,主要是因为 if 在 location 块中的行为不符合直觉,容易出现配置错误。但在 server 块中用 if 配合 return 做简单判断是安全的。

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

限流参数的选择

rate=10r/s 和 burst=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
│ └── ...

map 和 limit_req_zone 定义在 nginx.conf 的 http 块中,所有站点共享。

每个站点的 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 服务、内容管理系统、电商平台、在线服务