DDoS这个词,做运维和安全的同学几乎每年都要在告警群里见上几回。很多人第一次接触它,是在某个凌晨被电话叫醒——业务突然大面积超时,带宽被打满,监控面板一片飘红。可真要让人把DDoS讲清楚,多数人只能说出“大量请求把服务器压垮了”这一句,再往下问攻击分几层、每层怎么打、防御该在哪一层做,就说不下去了。这篇内容我想把DDoS这件事从头到尾拆一遍:它到底是什么、攻击者从哪些维度下手、不同攻击的流量特征长什么样、防御体系该怎么分层搭建、真被打的时候排查链路怎么走。适合刚入行的运维、安全方向的学习者,也适合需要给团队做安全预案的技术负责人。文中涉及的工具和命令都是通用思路,具体参数请结合自己的环境调整。
1. DDoS到底在打什么:从一次带宽打满的故障说起
1.1 一个典型的被打场景还原
假设你负责一套对外提供服务的系统,某天下午监控开始报警:入口带宽在几分钟内从日常的200Mbps飙到接近链路上限,用户侧反馈页面加载转圈、接口超时。你登上服务器看,CPU和内存都不高,应用日志也没有异常堆栈,但网卡收包速率异常,netstat里大量连接处于SYN_RECV状态。这时候基本可以判断:不是你的代码出了问题,是流量层面被人灌了。
这个场景里有个关键认知需要先建立起来——DDoS打的往往不是你的应用逻辑,而是你的资源上限。资源包括带宽、连接数、CPU、内存、磁盘IO,甚至包括上游DNS的解析能力。攻击者要做的就是用最小的成本,让你的某一项资源先耗尽,从而让正常用户进不来。理解这一点,后面的防御思路就顺了:防御的本质不是“识别坏人”,而是“保住资源”。
1.2 分布式这三个字才是难点
单点发起的流量攻击其实好防,一个IP限速就解决了。DDoS真正棘手的是“分布式”——攻击流量来自成千上万个不同的源地址,可能是被感染的终端、被控制的服务器、被滥用的开放服务。你没法简单地把某个网段拉黑,因为正常用户可能就在里面;你也没法靠单机防火墙扛,因为流量在到达你服务器之前就已经把上行链路堵死了。
这里要区分两个概念:流量型攻击和资源耗尽型攻击。流量型是硬灌带宽,你本地做什么都白搭,因为包根本到不了你的机器;资源耗尽型是打你的协议栈或应用层,比如耗尽连接表、拖慢数据库查询。前者必须在运营商或清洗中心层面解决,后者才轮得到你在主机和应用层做文章。很多新手一上来就在服务器上装一堆防护软件,结果流量型攻击一来,机器连SSH都连不上,软件根本没机会工作。
1.3 攻击成本和防御成本的天然不对等
做安全规划时必须有这个心理准备:攻击侧的边际成本远低于防御侧。攻击者用一批被控终端发起请求,成本可能只是租用一批资源的费用;而防御方要保证业务在任意流量下可用,需要带宽冗余、清洗设备、专家值守,投入是持续的。这种不对等决定了防御不能追求“完全挡住”,而要追求“在可接受成本下保住核心业务”。
所以实际工程里常见的策略是分级:核心交易链路重点保,静态资源和边缘业务可以降级甚至暂时摘除。这个取舍必须在平时就规划好,等被打的时候再临时决定,往往手忙脚乱。我在实际项目里见过太多团队平时不做预案,出事时所有人盯着监控干着急,连“先切哪个流量、先保哪个接口”都定不下来。
2. 按层拆解:攻击者到底从哪些维度下手
2.1 网络层与传输层:SYN Flood和UDP反射
网络层和传输层的攻击是最“粗暴”的一类,代表就是SYN Flood。TCP三次握手的机制是:客户端发SYN,服务端回SYN-ACK并把这个半连接放进队列,等客户端回ACK才算建立。攻击者伪造大量源IP发SYN,但从不回最后的ACK,服务端的半连接队列很快被占满,正常用户的SYN进不来。这个攻击的阴险之处在于,它消耗的是服务端的连接表资源,而不是带宽,所以小流量也可能打瘫一台配置不高的机器。
另一类是UDP反射放大。攻击者伪造目标IP,向一批开放的无连接服务(比如某些查询类服务)发请求,这些服务的响应包往往比请求包大很多倍,于是放大后的流量全部涌向目标。放大倍数取决于具体协议,有的能到几十倍。这类攻击的特点是源IP是真实的第三方服务,你封也不是、不封也不是,只能靠上游做特征识别和限速。
| 攻击类型 | 打的资源 | 典型特征 | 防御落点 |
|---|---|---|---|
| SYN Flood | 连接表/半连接队列 | 大量SYN_RECV,无后续ACK | 主机内核参数调优、SYN Cookie、上游清洗 |
| UDP反射放大 | 带宽 | 单一源端口、响应包远大于请求 | 上游清洗、协议层限速 |
| ICMP Flood | 带宽/设备CPU | 大量ICMP包 | 上游清洗、边界ACL |
2.2 应用层:慢速攻击和请求洪泛
应用层攻击更“聪明”,它模拟正常用户行为,只是把频率和并发拉到极端。典型的有HTTP Flood——大量看起来合法的GET/POST请求打向动态接口,每个请求都触发数据库查询或复杂计算,单看每个请求都不违规,但聚合起来就把后端拖垮。还有慢速攻击,比如Slowloris,用极慢的速度发送HTTP头,让服务端一直保持连接等待,慢慢耗尽连接池。
应用层攻击的难点在于它和正常流量混在一起,基于阈值的简单规则很容易误杀。防御要靠行为分析:同一IP的请求间隔是否异常规律、User-Agent是否高度雷同、请求路径是否集中在少数高消耗接口、会话建立后是否迟迟不完成。这些特征单看都不绝对,但组合起来就能把大部分自动化工具筛出来。实际部署时,WAF的规则要结合业务特点调,直接套默认规则往往误报率高得没法用。
2.3 混合攻击与“声东击西”
真实攻击很少只用一种手法。常见套路是先用流量型攻击吸引防守方注意力,把值班人员的精力全引到带宽上,同时用小流量的应用层攻击打核心接口。等你把清洗策略全压在网络层,应用层已经被拖垮了。还有一种更隐蔽的,攻击者先做长时间的低速探测,摸清你的防护阈值和响应时间,再在业务高峰期精准发力。
应对混合攻击的关键是监控要分层。带宽、连接数、QPS、响应时间、错误率这几个指标要同时盯,任何一个维度异常都要能独立触发告警。只盯带宽的团队,遇到应用层攻击时往往反应慢半拍,因为带宽看起来完全正常。
3. 防御体系怎么搭:从边界到应用的纵深布局
3.1 第一道防线放在上游,而不是自己机房
前面说过,流量型攻击在到达你机器之前就已经把链路堵了,所以第一道防线必须在运营商或云厂商的清洗能力上。具体做法通常是:把域名解析指向带有清洗能力的入口,正常流量透传,异常流量牵引到清洗中心过滤后再回注。这个切换要提前配置好,并且定期演练,确保真出事时能快速生效。
这里有个容易被忽略的细节:清洗阈值的设置。阈值设太低,正常业务高峰也会触发清洗,白白增加延迟;设太高,攻击来了半天不触发。合理做法是结合历史流量曲线,取高峰值的1.5到2倍作为触发线,同时配置手动强制清洗的通道,值班人员发现异常可以立即介入,不用等自动阈值。
3.2 主机层的内核参数与连接管理
流量到了主机这一层,能做的优化其实不少。针对SYN Flood,可以开启SYN Cookie,让服务端在握手完成前不分配资源;调整半连接队列和全连接队列的长度,避免正常突发流量被误伤;缩短SYN-ACK的重试次数,加快半连接的回收。这些参数在Linux下都有对应项,调整前要评估业务特性,比如长连接为主的业务和短连接为主的业务,参数取向完全不同。
# 查看当前半连接相关参数(示例,具体值按环境调整) sysctl net.ipv4.tcp_syncookies sysctl net.ipv4.tcp_max_syn_backlog sysctl net.core.somaxconn提示:内核参数调优只能缓解资源耗尽型攻击,对流量型攻击无效。不要指望调几个参数就能扛住大流量,那是上游的事。
3.3 应用层的限速、鉴权与降级
应用层是最后一道也是最能体现业务理解的一道防线。常见手段包括:按IP或用户维度做请求频率限制,对高消耗接口单独设更严的阈值;对关键操作加人机校验,把自动化工具挡在外面;准备降级预案,被打时先关掉非核心功能,把资源集中给主链路。
限速策略的设计要避免“一刀切”。比如登录接口和商品详情接口,正常用户的访问频率差很多,用同一个阈值必然出问题。我的经验是按接口分三档:高频只读接口放宽,写操作收紧,涉及资源消耗大的查询单独限。另外限速的响应也要讲究,直接返回错误可能刺激攻击者加大力度,返回一个带延迟的排队页反而更稳。
4. 真被打的时候:一条可复现的排查链路
4.1 先确认是攻击还是自身故障
告警响起来的第一分钟,最忌讳的就是直接下结论。先做三件事:看流量曲线是突增还是渐变,突增更像攻击,渐变可能是业务增长或代码问题;看源IP分布,攻击流量往往集中在少数网段或有明显的伪造特征;看请求特征,路径是否集中、参数是否异常、User-Agent是否雷同。这三步做完,基本能定性。
我遇到过一回,监控显示QPS暴涨,团队第一反应是被打了,结果查下来是新上线的客户端版本有个重试逻辑写错了,失败后疯狂重试。如果当时直接上清洗策略,反而会把正常用户误伤。所以定性这一步不能省。
4.2 抓包与流量采样怎么看
定性之后要抓证据。在边界做流量采样,看包的大小分布、协议分布、源端口分布。SYN Flood的特征是大量小包、源端口随机;反射放大的特征是响应包远大于请求、源地址是第三方服务。主机上用抓包工具抓一小段样本,重点看TCP标志位和连接状态分布。
# 统计当前连接状态分布(示例) ss -s # 按源IP统计连接数,找出异常集中的来源(示例) ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head采样时注意控制抓包量,别把磁盘写满,也别在已经高负载的机器上跑重活。抓包本身会消耗CPU,建议在旁路或低峰做,或者用轻量的采样方式。
4.3 处置顺序:先止血再溯源
处置的优先级永远是先恢复业务,再查来源。具体顺序:第一步启用上游清洗或切换高防入口,把流量型攻击挡在外面;第二步在边界做临时ACL,封掉特征明显的恶意源;第三步在应用层收紧限速和校验,挡住漏进来的应用层攻击;第四步才是慢慢分析攻击来源和手法,做长期加固。
这个顺序很多人会搞反,一出事就想追查是谁打的,结果业务一直挂着。溯源在多数情况下收益有限,攻击源往往是跳板,追下去也难有实质结果。把业务先救回来,才是对用户负责。
5. 几个容易踩的坑和长期建设建议
5.1 别把WAF当成万能挡箭牌
不少团队上了WAF就觉得高枕无忧,实际上WAF主要防应用层,对流量型攻击基本无能为力,而且规则需要持续调优。默认规则直接上线,要么误报把正常用户挡了,要么漏报让攻击穿过去。我的建议是WAF先跑观察模式一段时间,把误报规则挑出来调整,再逐步切到拦截模式。
5.2 预案要演练,不能只写在文档里
DDoS预案最怕的就是“文档里有、真出事没人会”。清洗切换、降级开关、值班响应,这些动作要定期演练,让每个值班的人都知道第一步做什么、找谁确认。演练时故意制造一些“意外”,比如切换后某个依赖没跟上,看看团队能不能快速发现。平时多流汗,战时少流血,这话在安全运维里一点不假。
5.3 容量规划要留冗余,但别盲目堆带宽
带宽冗余是必要的,但不是越多越好。盲目堆带宽成本高,而且遇到超大流量照样扛不住。更划算的做法是把钱花在分层防御上:上游清洗保底、主机参数调优、应用层限速兜底,三层配合起来,比单纯堆带宽的性价比高得多。容量规划时把历史峰值、业务增长预期、攻击历史都纳入考虑,留出合理余量即可。
5.4 日志和监控是长期资产
最后说一个容易被忽视的点:完整的流量日志和攻击记录是长期资产。每次被打之后,把攻击特征、处置过程、效果评估都归档,下次遇到类似手法能快速匹配。监控指标也要持续完善,把这次暴露出来的盲区补上。安全建设是个循环,每次事件都是把体系往前推一步的机会。
我在实际项目里的体会是,DDoS防御没有一劳永逸的方案,它更像一套需要持续维护的工程体系。工具和参数只是骨架,真正决定效果的是团队对业务的理解和平时积累的预案。把这些基础打牢,真遇到事的时候心里才有底。