安全!使用WAF.SB抵御恶意请求

Xay 网络相关 2025-06-11
上篇【加速!使用WAF.SB优化网站速度】一文中已经介绍了如何使用CDN加速网站访问.这里介绍一下利用CDN抵御第7层的拒绝服务攻击(DDoS攻击,也可以叫CC攻击)

前言

可以先用我初中学历的文化程度简单的白话文方式理解一下DDoS攻击类型(很不专业)

  • Layer4: 四层攻击普遍是基于TCP或者UDP的网络/协议层的攻击,就是常说的dd攻击,目的是耗尽目标服务器的带宽资源,导致目标服务器的网络拥塞,如果目标服务器带宽是1Gbps,那么理论最大传输速度就是125MB/s,此时攻击者每秒塞给你200MB数据,是吃不下的.
  • Layer7: 七层攻击属于应用层攻击,目的是使目标服务器的CPU/内存/网络连接数持续高占用,最终无法处理正常请求的行为,俗称cc攻击

需要注意的是,第四层攻击一般来说只能依靠上游的网络服务提供商提供有效的防御措施,需通过专业的硬件防火墙设备,路由策略进行防御以及足够的冗余带宽进行流量清洗,而第七层的攻击既然是针对应用层的攻击,是可以通过软件层一定程度上进行缓解,本文着重介绍如何通过软件层缓解大量恶意请求,继续以我们提供的CDN服务做一篇经验分享性质的文章,触类旁通,使用任何WEB防火墙或CDN产品均同理可循


安全优化基础指南

先不说具体的防御措施,从性能调优上可以先做一定的基础措施
保护源站并发阈值:设置请求限制
设置请求限制
如果请求被识别为正常请求,那么被请求的是非缓存内容的话,CDN节点会向源站拉取数据并返回给用户浏览器,这个请求频率和数量一旦过高,CDN节点会对源站造成高并发高负载,这里可以根据自身业务设置合适的请求限制,如最大并发连接数设置为300,超过300并发时CDN将直接给用户返回429状态码,这种情况有可能会阻止用户的正常访问,但是作为兜底保护了源站负载健康.

减少不必要的回源请求:设置缓存
静态资源使用缓存功能,不请求源站服务器.需要注意的是,攻击者通常会设置Cache-Control: no-cache等请求标头,向服务器提交不缓存请求试图绕过缓存,建议在缓存设置中不要设置任何跳过的Cache-Control值
不允许跳过缓存


防御实践——基础

启用CC防护
CC防护设置
使用上图设置方式可以拦截大多数常见攻击,但需要注意的是,如果使用的网站包含大多数API调用或非常规客户端,最好使用例外URL来排除相应URL以免误拦截正常请求.

启用5秒盾
5秒盾设置
如果你的网站目前遭受大规模攻击,且不具备根据采样攻击特征进行自定义WAF规则的能力的话.可以首先开启5秒盾保障浏览器用户可以正常访问网页


防御实践——进阶

启用WAF
启用WAF

  • 人机识别验证方式: 请务必使用验证码,滑动验证和点击验证很容易绕过
  • 启用系统全局规则: 使用我们预置的WAF策略,绝大多数情况下足以应付市面上常见洪水和绕过

使用国家地区封禁
区域封禁
低门槛低成本的攻击方式,其攻击来源往往主要力量来自海外,如果你的网站面向群体主要为国内用户,可以使用区域封禁.该方法简单粗暴但能很有效缓解攻击强度


防御实践——WAF高级玩法

先在WAF -> 入站规则中新增一个分组,命名随意
添加自定义WAF分组

添加限速策略
进入刚刚创建的自定义分组,创建一个新的规则集
新增规则集
规则使用CC统计,在添加规则集处,点击使用代码先添加我提供的三个基础策略,后续根据自身条件从中修改
规则1: CC统计-完整URL👇

{
  "id": 0,
  "isOn": true,
  "name": "CC统计-完整URL",
  "code": "",
  "description": "",
  "connector": "or",
  "ruleRefs": null,
  "rules": [
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "60",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}",
          "${requestURL}"
        ],
        "period": 30,
        "threshold": 60
      },
      "description": ""
    },
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "100",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}",
          "${requestURL}"
        ],
        "period": 60,
        "threshold": 100
      },
      "description": ""
    }
  ],
  "ignoreLocal": false,
  "ignoreSearchEngine": true,
  "actions": [
    {
      "code": "block",
      "options": {}
    }
  ]
}

规则2: CC统计-访问路径👇

{
  "id": 0,
  "isOn": true,
  "name": "CC统计-访问路径",
  "code": "",
  "description": "",
  "connector": "or",
  "ruleRefs": null,
  "rules": [
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "100",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}",
          "${requestPath}"
        ],
        "period": 30,
        "threshold": 100
      },
      "description": ""
    },
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "180",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}",
          "${requestPath}"
        ],
        "period": 60,
        "threshold": 180
      },
      "description": ""
    }
  ],
  "ignoreLocal": false,
  "ignoreSearchEngine": true,
  "actions": [
    {
      "code": "block",
      "options": {}
    }
  ]
}

规则3: CC统计-客户端IP👇

{
  "id": 0,
  "isOn": true,
  "name": "CC统计-客户端IP",
  "code": "",
  "description": "",
  "connector": "or",
  "ruleRefs": null,
  "rules": [
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "150",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}"
        ],
        "period": 30,
        "threshold": 150
      },
      "description": ""
    },
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "300",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${remoteAddr}"
        ],
        "period": 60,
        "threshold": 300
      },
      "description": ""
    }
  ],
  "ignoreLocal": false,
  "ignoreSearchEngine": true,
  "actions": [
    {
      "code": "block",
      "options": {}
    }
  ]
}

规则4: CC统计-UAM👇

{
  "id": 0,
  "isOn": true,
  "name": "CC统计-UAM",
  "code": "",
  "description": "",
  "connector": "and",
  "ruleRefs": null,
  "rules": [
    {
      "id": 0,
      "isOn": true,
      "param": "${cc}",
      "paramFilters": [],
      "operator": "gt",
      "value": "1000",
      "isCaseInsensitive": true,
      "isComposed": true,
      "checkpointOptions": {
        "enableFingerprint": true,
        "ignoreCommonFiles": true,
        "keys": [
          "${host}"
        ],
        "period": 60,
        "threshold": 1000
      },
      "description": ""
    }
  ],
  "ignoreLocal": false,
  "ignoreSearchEngine": true,
  "actions": [
    {
      "code": "captcha",
      "options": {}
    }
  ]
}

以上4个规则的优先级需按照指定下列顺序排列

  1. CC统计-完整URL
  2. CC统计-访问路径
  3. CC统计-客户端IP
  4. CC统计-UAM

对每个规则做一下基础解释
CC统计-完整URL
CC统计-完整URL
这里统计对象是客户端IP地址和完整的URL计数,阈值是每30秒60次,完整URL即包含请求方法(GET|POST等)、请求协议(http://|https://),主机名(xay.ee)、请求路径(/admin这种)、请求URI(index.php?do=login)类似这种https://xay.ee/archives/network/securing-websites-with-waf-sb
也就是说,同一个IP访问https://xay.ee/archives/network/securing-websites-with-waf-sb这个完整的地址30秒内超过60次会被封禁,同时我还有一个规则使用的相同的统计对象,但是使用了不同的阈值(60秒内100次)进行兜底,条件之间的关系使用或(OR)

CC统计-访问路径
CC统计-访问路径
上面说过,请求路径类似/admin这种,但是可能不同类型的页面在同一个路径下,就拿博客来说,同一个分类下可能有多篇文章,所以应该使用比完整URL更宽松的限制阈值

CC统计-客户端IP
CC统计-客户端IP
这里只使用客户端IP作为统计,也就是说无论客户端访问的什么,只要在限定时间内超过一定次数,就封禁,这个阈值应该设置得比前两个更高,具体根据自身业务需求和源站承载能力进行酌情设置

CC统计-UAM
CC统计-UAM
这个策略其实更有意思。属于兜底性质的策略,统计的对象只有主机名,而不统计客户端IP。意思就是无论访问者是谁,只要当前网站域名60秒内被请求超过1000次,意味着当前网站处于被攻击状态,只要不是白名单中的IP,都会弹出验证码进行人机验证

自建WAF条件记得勾选以下选项

  • CC统计中的检查请求来源指纹
  • CC统计中的忽略常用文件
  • WAF规则集中的允许搜索引擎

小测验

现在我们运行一个小CC脚本,目标是本文链接https://xay.ee/archives/network/securing-websites-with-waf-sb,启动
看看CDN上的访问日志,我开启了只记录WAF日志
WAF日志

源站负载

可以看到WAF已经开始拦截了,并且源站负载并没有什么影响。

评论(1)

发布评论
  1. 路人甲 路人甲

    不错