去年十月的一个晚上,手机收到监控报警,说站点打不开了。
打开电脑一看,首页能出,但转圈转了十几秒,其他页面全是 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、本站资源仅限个人学习研究使用,严禁用于任何违法违纪用途。因使用者违规使用产生的一切后果,由使用者自行承担,本站不承担任何责任。


评论(0)