本文主要介绍如何通过ModSecurity,来拦截单个IP对服务器的CC攻击或采集行为。
该教程主要针对Apache,如果使用的是Nginx,则建议使用Nginx自带的HttpLimitReqModule模块进行防御,因为规则中的部分指令在ModSecurity V3版本中暂不支持,最终的效果是只要达到设定的攻击阈值,就会将IP地址进行永久封禁,除非重新加载Nginx,虽然看似更安全,但是封禁的IP信息会保存在内存中,随着封禁IP数量的增加,占用的内存也会越来越大,这部分内存只会在Nginx重新加载时才会释放。
2024年4月7日更新:Modsecurity V3.0.11及以上版本已支持CC防御。
在OWASP规则中,已经包含了对应的防止CC攻击或采集的规则,我们只需进行简单的配置即可。
首先,在crs-setup.conf文件中,找到ID为900260、900700的两条规则,并取消注释:
SecAction \ "id:900260,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'" SecAction \ "id:900700,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:'tx.dos_burst_time_slice=60',\ setvar:'tx.dos_counter_threshold=100',\ setvar:'tx.dos_block_timeout=600'"
ID为900260的规则定义了一些静态资源的后缀名,在判断是否是CC攻击或采集行为时,此类静态资源的访问不在计数范围内。
ID为900700的规则定义了CC攻击判定的一些参数,即如果在60秒内(tx.dos_burst_time_slice),IP地址的访问频率达到了100次(tx.dos_counter_threshold),就被判定为一次攻击嫌疑(但此时并不会将IP地址进行封禁,下方会解释),而一旦将IP地址封禁,600秒后(tx.dos_block_timeout)才会解封。
上述规则会与REQUEST-912-DOS-PROTECTION.conf文件中的规则进行联动,只有出现两次连续的攻击嫌疑判定,才会将IP地址封禁,即,在第一个60秒内,IP地址的访问频率达到了100次时,以访问达到100次时的时间为开始进行计算,下一个60秒如果依然达到了100次的访问,则会将IP地址封禁600秒。
比如,12:00:00-12:01:00期间,访问次数达到了100次,此时被判定为一次攻击嫌疑;访问达到100次时的时间如果是12:00:15,则从12:00:15开始计算,12:00:15-12:01:15期间,访问次数又达到了100次,此时才会将IP地址进行封禁。
如果希望60秒内达到100次访问时就立刻将IP地址封禁,则需要修改REQUEST-912-DOS-PROTECTION.conf文件中的两条规则,将ID为912161的规则注释掉,将ID为912170的规则的判断条件“@ge 2”改为“@ge 1”,如下所示:
#SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" \ # "id:912161,\ # phase:5,\ # pass,\ # t:none,\ # nolog,\ # tag:'application-multi',\ # tag:'language-multi',\ # tag:'platform-multi',\ # tag:'paranoia-level/1',\ # tag:'attack-dos',\ # chain" # SecRule &IP:DOS_BURST_COUNTER "@ge 1" \ # "setvar:'ip.dos_burst_counter=2',\ # setvar:'!ip.dos_counter',\ # expirevar:'ip.dos_burst_counter=%{tx.dos_burst_time_slice}'" SecRule IP:DOS_BURST_COUNTER "@ge 1" \ "id:912170,\ phase:5,\ pass,\ t:none,\ log,\ msg:'Potential Denial of Service (DoS) Attack from %{tx.real_ip} - # of Request Bursts: %{ip.dos_burst_counter}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'paranoia-level/1',\ tag:'attack-dos',\ setvar:'ip.dos_block=1',\ expirevar:'ip.dos_block=%{tx.dos_block_timeout}'"
配置完成后,可根据自身实际情况,调整tx.dos_burst_time_slice、tx.dos_counter_threshold、tx.dos_block_timeout参数的值即可,同时需要注意的是,crs-setup.conf文件中SecCollectionTimeout参数的值,需大于等于tx.dos_block_timeout参数的值。
此时还留有一个隐患需要解决,权重较高的网站,搜索引擎访问会比较频繁,如果搜索引擎的访问也触发了设定的阈值,搜索引擎的IP也会被封禁,此时有两种解决方案,一种是将搜索引擎的IP地址添加白名单,但难度较大,因为搜索引擎官方几乎不对外公布自己的所有IP。
另外一个方法是,可以在服务器内多绑定一个IP地址,然后在域名解析处额外添加一条解析,如果是搜索引擎,则访问另外一个IP地址(目前很多第三方DNS解析已支持按搜索引擎进行解析,如DNSPOD),如下图所示:
解析设置后,我们同样需要添加一条规则,针对为搜索引擎提供访问的IP,取消CC防护规则,规则如下,需放置在REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf文件中:
SecRule SERVER_ADDR "@ipMatch 服务器IP" "id:1001,phase:1,pass,nolog,ctl:ruleRemoveByTag=attack-dos"
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。