聊聊 CC 攻击、limit_req|conn、nginx_lua 和 防御思路
关于 CC 攻击方面的知识,关注了好几个月,有一些体会聊一下。
百度百科:CC攻击(Challenge挑战 Collapsar黑洞 Attack攻击)是 DDOS(Distributed分布式 Denial拒绝 of Service服务)的一种。
DDOS 攻击分为 D + DOS。
DOS ⌈拒绝服务攻击⌋ 以消耗网络带宽或系统资源为目的,导致网络带宽占满、系统不胜负荷以至于瘫痪而停止提供正常的服务。
D+DOS 是借助数百、甚至数千台被入侵后安装了攻击进程的主机同时发起的集团行为,是分布式的 DOS 攻击。
我们常说的 DDOS 通常在三层网络层和四层传输层,如SYN/ACK、UDP、ICMP FLOOD ⌈洪水⌋攻击,即利用网络协议,需要控制大量的肉机。
DDOS 一般我们是防御不了的,几、几十 Gbs 的防护能力,需要专业的高防产品。
而 DDOS 中的 HTTP Flood 俗称 CC 攻击,是针对 Web 服务在第七层 ⌈应用层⌋ 协议发起的攻击,也就是 GET、POST、OPTION、HEAD 请求,黑客伪造成合法数据包,模拟正常用户访问网站的请求,成本较低,比如压测工具也能轻松打垮一个网站。
Web 攻击个人开发者是可以防御的,它的攻击方式无非是单 IP 频繁的刷页面,或者多 IP 同时访问,其中单 IP 一般通过访问频率限制,多 IP 是较难防御的。
针对上面两种情况,很多采用 nginx 自带的 limit_req
⌈限制速率⌋ 和 limit_conn
⌈限制并发⌋来解决,布置较为方便,但也有不足。我们通过与 nginx_lua
对比来说明。
拒绝方式比较生硬。两者在访问超出限制时默认返回 503 页面 ⌈503 是标准状态码,告诉访问者服务暂时不可用,一会再来⌋,容易让访问者误认为网站出故障了。可以指定状态码,并自定义错误页面友好的提示。
lua 的速率、计数组件,可自定义超限后的动作。如显示验证码页面。
不能阻止单 IP 恶意访问的持续攻击。
limit_req
是速率限制,一般只统计doc
访问 ⌈不包含css js⌋,但如果攻击者持续攻击,很明确是恶意访问,并不能阻止该 IP 的继续访问。这个问题,一般需要另外单位时间内计数的方式解决,比如 N 秒内访问达到多少次,封禁该 IP,通过 sh 脚本统计日志加入黑名单,或者安装三方软件来补充这个功能。但这种不能太苛刻,适合 ⌈非常过分⌋ 的访问,另外实现细节上有一点麻烦,比如 nginx 日志排除 js 等资源访问个数、封禁多长、如何解禁的问题。lua 共享内存或连接 redis 来维护黑白名单及封禁时间。
limit_conn
限制并发数,这个并发指的是正在连接状态的个数,个人觉的针对单 IP 应用限制并发是鸡肋,有limit_req
就足够了,它的优势是防止群攻,也就是针对某个域名或某个location
应对多 IP 同时攻击的情形,但整体的限制,会误伤正常的访问。lua 的并发组件,超出并发时刷掉异常流量(机器)。
蜘蛛。蜘蛛的访问频率可能较高,应用限流时需考虑到。解决的办法是一般云上比如腾讯云可以把蜘蛛区分到指定的服务器,但不能全部识别,从观察上来看,大部分百度蜘蛛可以识别,其他如搜狗、360等大部分还是不能识别,而蜘蛛往往有短时间内大量访问的情况。这个问题可以在 nginx 中匹配
userAgent
带有蜘蛛标识导到单独location
。lua 采集维护蜘蛛IP库,或动态识别,使蜘蛛不应用防御,或者应用宽松的防御。
不能灵活配置。更改配置需进入服务器,修改,然后
nginx -s reload
。lua 通过外部 API 来修改配置文件即可,无需重启 nginx。
当网站正在遭受攻击时,没有应急措施。
lua 可以编写人机校验程序、调整配置
实际复杂情况下 limit_req
和 limit_conn
是不够灵活的,很多网站通常的做法是应用防火墙,对频繁或者大量访问的进行人机识别,显示图形验证码页面或者 用户无感知的 cookie校验
、js挑战
等。一般是 N 时长内访问 N 次显示图形验证、而当并发量达到阈值进行用户无感知的全面人机校验。
防火墙产品中的 CC 防御,开发者很多采用 nginx_lua
,流行的 openresty
。
防御的思路,监测手段:一速率限制,二并发限制,三计数,这三个在 openresty
中有成熟组件。执行动作:图形验证,人机识别,封禁。
防御策略,不同目标的不同防御策略,识别蜘蛛、识别假蜘蛛、识别杂牌蜘蛛,根据 header
头信息如 userAgent
、 ip
段、国家地区等运用不同的防御。
其他措施:缓存、代理缓存。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: