首页 应用实战正文

ModSecurity防CC攻击、防采集规则配置

王子 应用实战 2020-05-16 1850 0

本文主要介绍如何通过ModSecurity,来拦截单个IP对服务器的CC攻击或采集行为。

该教程主要针对Apache,如果使用的是Nginx,则建议使用Nginx自带的HttpLimitReqModule模块进行防御,因为规则中的部分指令在ModSecurity V3版本中暂不支持,最终的效果是只要达到设定的攻击阈值,就会将IP地址进行永久封禁,除非重新加载Nginx,虽然看似更安全,但是封禁的IP信息会保存在内存中,随着封禁IP数量的增加,占用的内存也会越来越大,这部分内存只会在Nginx重新加载时才会释放。


在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),如下图所示:

image.png

解析设置后,我们同样需要添加一条规则,针对为搜索引擎提供访问的IP,取消CC防护规则,规则如下,需放置在REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf文件中:

SecRule SERVER_ADDR "@ipMatch 服务器IP" "id:1001,phase:1,pass,nolog,ctl:ruleRemoveByTag=attack-dos"


版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。