故事从一条短信开始
那天早上 7 点 48 分,我被一条短信震醒。
【XX 云】尊敬的用户,您的账户余额低于预警阈值,请及时充值以保证服务正常运行。
我揉着眼睛点开后台,倒吸一口冷气:
- 流量包:消耗 98%
- CDN 用量:是平时的 47 倍
- 总账单:已扣 387 元(前一天我的账单是 4 块 2)
这是一个我用爱发电了大半年的小工具站,平时 DAU 不到一千。它不可能一夜之间烧掉我半个月的咖啡钱。
打开 Nginx 的 access.log,瞬间懂了——有人在刷我的接口,每秒上百次。
那一天我熬到傍晚,终于把流量打回正常水平。这篇文章不是"反爬教程",而是一份踩坑实录:从我一开始用最朴素的 ban IP 被打脸,到后来才搞懂"封 IP 不如识 IP"——这中间我交的智商税,希望能省你一些。
一、最朴素的第一反应:封 IP
打开日志,最先映入眼帘的是这样的请求:
123.45.67.89 - - [08:14:23] "GET /api/search?q=xxx HTTP/1.1" 200 1247
123.45.67.89 - - [08:14:23] "GET /api/search?q=yyy HTTP/1.1" 200 1183
123.45.67.89 - - [08:14:24] "GET /api/search?q=zzz HTTP/1.1" 200 1294
...
清一色的同一个 IP,每秒打十几次 /api/search。
简单粗暴,加进 Nginx 黑名单:
deny 123.45.67.89;
nginx -s reload,搞定。
10 秒后,日志里冒出来另一个 IP,频率一模一样。
再封。
20 秒后,又来一个。
我意识到不对劲——这哥们手里有一池IP。我那时还以为自己发现了什么大秘密:原来真有这种"分布式爬虫"。
💡 后来我才知道: 现在网上随便一个住宅代理服务商,1000 个 IP 包月只要几十块,按量付费的甚至几毛钱一个新 IP。封 IP 在 2025 年这个时间点,已经是性价比最低的反爬手段。 你封一个他换一个,你的 nginx.conf 越来越长,他的成本几乎为零。
二、第二招:限流。然后我误伤了真用户
封 IP 不行,那就限流——同一个 IP 一分钟超过 60 次就 429。
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m;
部署上去十分钟,问题来了。
真实用户开始投诉打不开页面。
排查之后发现两类误伤:
- 公司局域网用户——一个公司几十号人共用一个公网出口 IP,一限就误伤一片。
- 手机 4G 切 WiFi 的用户——运营商的 NAT 池里几百号人共用 IP,刷两下就被限。
而那个爬虫呢?它的 IP 池里每个 IP 一分钟也就请求十几次,根本触不到我设的阈值。
我第一次意识到一个反直觉的事实:
🎯 基于 IP 频率的限流,只能拦住"懒爬虫"。一个稍微懂点事的爬虫,会用 IP 池把每个 IP 的请求频率控制得比真人还低。
到这一步,我已经被打了两个耳光。账单还在涨。
三、转折点:我开始研究"这些 IP 都是什么 IP"
冷静下来之后,我决定换个思路:与其拦请求,不如先搞清楚来的人是谁。
我把日志里前一小时所有疑似爬虫的 IP 抠出来,去重,得到大约 800 多个 IP。然后我做了一件之前从来没做过的事——逐个查这些 IP 的"身份"。
这一查,新世界的大门打开了。
我用了 BiuPing 的 IP 信誉查询(最近他们刚上的功能,免费)抽样查了几十个,发现这些 IP 的画像高度一致:
| 维度 | 爬虫 IP 表现 | 真实用户 IP 表现 |
|---|---|---|
| 类型 | 90% 标记为「数据中心 / IDC」 | 95% 是「住宅 / 移动网络」 |
| 代理标记 | 大量被识别为代理/VPN | 几乎不带代理标记 |
| 黑名单命中 | 多数在 1-3 个威胁库里被举报过 | 极少命中 |
| 风险评分 | 平均 70+ 分(满分 100,越高越危险) | 普遍在 5 分以下 |
| 国家归属 | 集中在几个海外机房友好型地区 | 中国大陆为主 |
我把这个表打印出来贴在显示器旁边。这是这次踩坑最大的收获。
四、一个 IP 能告诉你的事,远比你想象的多
我之前以为 IP 就是个数字,最多能查到运营商和省份。后来才发现,每一个 IP 在互联网上都有一份"档案",包括:
1. 它是住宅 IP 还是机房 IP
- 住宅 IP:电信/联通/移动分配给家庭宽带、手机的 IP,背后大概率是真人。
- 机房 IP(IDC/Datacenter):阿里云、腾讯云、AWS、DigitalOcean 这些数据中心的 IP。正常用户不会从机房 IP 访问你的网站——除非他自己在云服务器上写了脚本。
🧠 划重点: 一个看起来是中国某城市的 IP,它的归属地"信息"和"类型"可以完全不一样。机房 IP 也有归属地(机房在哪它就显示哪),但类型字段会写明这是 IDC。只看归属地不看类型,会被骗到。
2. 它是不是已知的代理 / VPN / Tor 出口
全球有公开维护的代理列表、VPN 出口列表、Tor 出口节点列表。一个 IP 如果出现在这些列表里,访问你的业务时应当被多看两眼——不是要直接 ban,但至少应该提高它的"可疑度评分"。
3. 它是不是被举报过
像 AbuseIPDB、Spamhaus、Project Honey Pot 这些威胁情报库里,每天有大量 IP 因为发垃圾邮件、暴力破解、扫端口、DDoS 被全球受害者举报。一个被几十个独立站点举报过的 IP,几乎不可能是来你这看小说的真用户。
4. 综合风险评分
把上面这些维度加权得到一个 0-100 的分数。我自己的经验值是:
- 0-30:普通用户,放行
- 30-60:灰色地带,加滑块/人机验证
- 60+:高风险,直接拒绝或返回假数据
五、改造方案:从"封"到"识"
想清楚之后,我把 Nginx 那一坨 deny 全删了,重写了风控逻辑。架构大概是这样:
用户请求
↓
Nginx → 转发到风控网关 (Lua/Go 写的小服务)
↓
风控网关查询:
├─ 这个 IP 之前来过吗?(本地 Redis 缓存)
│ ├─ 是 → 用缓存的信誉分
│ └─ 否 → 查询 IP 信誉数据,结果回写 Redis(TTL 24h)
↓
根据信誉分决策:
├─ < 30 → 直接放行
├─ 30-60 → 在前端弹滑块/人机验证
└─ ≥ 60 → 返回 403 或假响应
↓
真实业务接口
几个关键设计:
1. 必须做缓存。 IP 信誉数据不是每次请求都现查的,那样性能扛不住、调用成本也吃不消。第一次见到的 IP 才查,查完结果丢 Redis 缓存 24 小时。绝大多数请求都命中缓存,性能几乎没影响。
2. 灰度放行,别一刀切。 60 分以上直接 ban,但 30-60 分这一段千万别 ban——这一段里混着大量公司 NAT 出口 IP、机场 WiFi、公共 WiFi。给它们弹个滑块即可,体验损失最小。
3. 假响应比 403 好用。 对评分极高的恶意 IP,别返回 403——这等于告诉对方"我识破你了",对方会立刻换策略。返回一个看起来正常的、但数据是假的响应,让爬虫把脏数据吃下去。这招对内容站尤其有效。
4. 不要信任前端 IP 字段。 一定要从 Nginx 透传的 X-Forwarded-For 里拿真实 IP,且只信任最左边那个(最靠近用户的)。这一步搞错的话,你拿到的全是 Nginx 自己的 IP,整个风控就废了。
部署完之后第二天,账单回到 5 块钱以内,CPU 也安静了。
事后我跑了一下数据:那一波"攻击"里,91% 的请求来自机房 IP,6% 来自已知代理池,剩下 3% 是漏网之鱼。 如果我一开始就识别 IP 类型而不是封 IP,那 387 块学费可以省下来。
六、把这套东西用到日常运维里
后来我意识到,IP 信誉这件事不只在"被刷爆"的时候有用,平时也用得上:
1. 注册接口保护。 注册接口是垃圾账号重灾区。在注册时拦截一下风险 IP,能干掉 80% 的批量注册脚本。
2. 评论 / 内容发布。 防垃圾评论,传统是接谷歌 reCAPTCHA。但 reCAPTCHA 在国内访问慢、对真用户体验差。先做一道 IP 信誉过滤,可以让 90% 的真用户绕过验证码,体验一下子上去了。
3. 排查异常订单。 电商业务里,用机房 IP 下单的,几乎 100% 不是真实买家。要么是黄牛脚本,要么是测试,要么是欺诈。这个维度比"同一收货地址下多单"更早一步。
4. 调试自己业务的访问情况。 写完一个新接口,想知道全国各地访问它的速度、是否有路由问题,可以先用 BiuPing 多节点 Ping 跑一轮看延迟分布;想知道接口在各地的 HTTPS 握手有没有问题,用 网站测速 看瀑布流。这些跟反爬不直接相关,但属于平时排查"为什么有的用户慢"的常用手段。
七、写给独立开发者的几句真心话
我不是搞安全出身的,这次是被打懵了之后现学现卖。如果你也是写小工具站、独立产品的开发者,下面几句肺腑之言:
1. 永远开账单告警。 不是流量告警,是账单告警。流量告警可能在你睡觉的时候不痛不痒,账单告警一定会吵醒你。早一小时醒来,可能就少烧几百块。
2. 接口加缓存比加风控更便宜。 一个频繁被打的接口,第一反应应该是"它的结果能不能缓存"。能缓存的话,被刷一万次也只是把缓存读爆,源站根本不会慌。
3. 别给 GET 接口设计成"参数随便变"。 我那个 /api/search?q=xxx 之所以被针对,就是因为 q 一变 URL 就变,CDN 缓存命中率为零。改成"q 标准化 + 限定字符集"之后,命中率从 0% 升到 78%,被刷的成本对方扛不住就放弃了。
4. 保留 1-2 周的完整日志。 你不知道哪天会需要它。这次复盘我能写出来,全靠当晚没急着 logrotate。
5. 对 IP 这件事多一点敬畏。 一个 IP 不是一个数字,它身后有一整张档案。学会识别 IP,比学会封 IP 重要得多。
八、最后
写这篇的时候我又翻了一下当时的账单截图,387 块。
看起来不多,但对一个用爱发电的独立项目来说,等于直接吃掉两个月的服务器钱。这次之后我养成了一个习惯:每接入一个新接口、上一个新功能之前,先想清楚"如果有人恶意刷它,我会损失什么"。想清楚了再上线。
如果你也在做小项目、独立站、API 服务,这篇文章里的坑你可能早晚都会踩。不如先把它收藏了,下次半夜被账单短信吵醒的时候,至少还有人陪你一起骂街。
最后留个开放问题:
你做项目的时候,被薅得最惨的一次是怎样?后来怎么解决的?
评论区聊聊,让那些没踩过坑的同行也长长见识 👀
文中提到的工具:
都在 biuping.com,免费,无需注册。我自己的开发书签里钉了大半年了。