去年十月的一个晚上,手机收到监控报警,说站点打不开了。

打开电脑一看,首页能出,但转圈转了十几秒,其他页面全是 502。宝塔面板里 CPU 100%,负载 40 多。

先看了一眼访问日志,一秒钟两百多条请求,全是从同一个 IP 段过来的,UA 每次都不一样。

先止血,别先分析

当时我最开始想的是"先搞清楚是谁打的",结果查了十分钟,站点彻底挂了。

正确顺序是先让站活过来,再慢慢查。

第一步,把攻击 IP 段直接封掉。宝塔的防火墙里可以批量加,也可以直接写 nginx:

deny 45.13.0.0/16;
deny 91.240.0.0/16;

封完负载从 40 掉到 8,站点能打开了。

第二步,加限流。nginx 自带的两个模块够用:

# 在 http 块里
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

# 在 server 块里
location / {
    limit_req zone=req_limit burst=20 nodelay;
    try_files $uri $uri/ /index.php?$args;
}

意思是单 IP 每秒最多 10 个请求,允许突发 20 个,超出的直接返回 503。

注意 limit_req 是按 IP 算的,如果攻击方用的是分布式的,这个规则就没什么用,只是拖延。

这次攻击是什么类型

看日志会发现两个特征:

一是请求的都是首页和搜索页,这些页面要查数据库,最耗资源。

二是 UA 全都在变,但 IP 集中在三个段。说明不是真用户。

这种叫 CC 攻击,本质是用大量请求把数据库连接占满,让 PHP-FPM 进程全部卡住,新请求进不来就是 502。

和 DDoS 不一样。DDoS 是打流量,带宽打满,机房直接把 IP 黑洞。CC 是打应用层,带宽没满,但服务器处理不过来。

所以清洗流量的那种高防对 CC 效果一般,得在应用层挡。

临时方案和长期方案

临时:封 IP、限流、把搜索页暂时关掉。这几个动作五分钟能做完。

长期:上 CDN。

我一开始不想上 CDN,因为源码站图片多,流量费心疼。但被打了三天之后算了一下:CDN 一个月的钱,还不够我熬夜三天的时间成本。

上 CDN 有两个好处:一是真实 IP 被藏起来了,攻击方打的是 CDN 节点;二是静态资源全部由 CDN 扛,源站压力小一大截。

配的时候注意两点:

  • 回源只放行 CDN 的 IP 段,其他一律拒绝,不然攻击方绕过 CDN 直接打源站,等于白上
  • 开启"回源鉴权"或者自定义 header 校验,防止别人把你的域名解析到他的 CDN 上盗刷

事后算账

攻击持续了三天,第四天自己停了。

三天里站点基本处于半瘫状态,访问量掉了一半,恢复之后又花了大概一周才回到原来水平。

钱上损失不大,几百块的 CDN 流量费。

但有个隐形损失:那几天正好有一批新源码要上,全部推迟了。

几件现在会提前做的事

监控要先有。我那次能及时知道,是因为有个 uptime 监控每五分钟探一次。没有这个,可能挂一晚上都不知道。

日志要留。nginx 默认日志会滚动,被打了之后想回溯,发现早被覆盖了。现在我把访问日志按天切割,保留 30 天。

静态页面能救急。站点挂了之后,我给首页做了个纯静态版本,nginx 直接返回 html,不经过 PHP。这样至少首页能看,用户不会以为站没了。

被攻击这件事,防不住是常态。能做的是:快速知道、快速止血、别让源站裸奔。

俗人源码网免责声明:

1、本站所有资源均收集于互联网,分享目的仅限学习与参考。如有侵权,请联系 1685698671@qq.com 及时删除!

2、本站资源不保证完整性和安全性,下载后请自行检测。使用过程中出现的任何问题均与本站无关,敬请自行处理。

3、本站资源仅限个人学习研究使用,严禁用于任何违法违纪用途。因使用者违规使用产生的一切后果,由使用者自行承担,本站不承担任何责任。