干安全这行十几年,每逢大促活动保障,听得最多的汇报就是"我们又挨打了"。很多朋友一听到DDoS三个字母就紧张,但真要问起来,DDoS到底是什么、怎么打进来的、到底怎么防,能讲清楚的人其实没几个。很多团队的防御方案就是"买点高防IP"或者"加带宽",真到被打穿的那一刻才发现兜不住。这篇文章我把DOS和DDoS的原理、主流攻击手法、防御策略和应急流程完整拆解一遍,全程以防御视角来写,读完你至少能搞明白自己该在哪个层面做防护。
这套内容适合三类人:一是被攻击过但不知道怎么系统防御的技术负责人,二是刚接触安全、想建立完整知识框架的运维和开发者,三是不直接管安全但需要评估成本方案、做技术决策的架构师。我把原理讲明白,把防御链路讲透,再把踩过的坑都摊开说。
1. 理解DDoS攻击的底层逻辑
1.1 从一次真实攻击说起
先描述一个场景。某电商平台在促销前夜接到报警,入口网关的CPU突然跑到100%,流量监控曲线像被拉直的钓鱼线一样陡直上升,带宽飙到了几十Gbps,常规业务请求基本全部超时。运维打开监控面板一看,来自几千个IP的请求在疯狂砸首页登录接口,每个IP的请求频率并不高,但架不住IP总数太多,清一色的自动化流量。
这就是典型的分布式拒绝服务攻击。攻击者控制的机器不是一台两台,而是成百上千台,甚至在特定场景下可以达到数十万个受控节点。这些节点在同一时间向目标发起请求,把目标的带宽、CPU、内存、连接表消耗殆尽,导致正常用户无论如何都挤不进来。
这次事件最终通过紧急接入某安全厂商的流量清洗服务,把攻击流量引流到清洗中心过滤后再回注到源站,业务才在十几分钟后恢复。事后复盘,问题不在于没有防护手段,而是缺少预案——没人提前梳理过"哪些端口必须暴露、哪些请求频率属于异常、清洗设备的接入方式是什么"。
1.2 为什么传统防护在DDoS面前显得乏力
很多人有一个直觉误区:服务器配置高一点、带宽大一点,总能扛住吧?实际上DDoS的攻击成本远低于防护成本,双方在根本层面是不对等的。
从成本角度算一笔账:攻击者利用的是现成的僵尸网络,或者按小时租用流量发包服务,发起一场持续半小时的几十Gbps攻击,成本可能只需要几百块。而防守方为了扛住这次攻击,需要按月支付高防IP费用、准备数倍冗余带宽、部署清洗设备和WAF规则,动辄数万甚至数十万。攻击者可以随时换端口、换协议、换攻击手法,而防守方只能被动地一层层补防御。
另一个核心问题是攻击面太广。网络层有SYN Flood、UDP Flood、ICMP Flood,传输层有连接耗尽类攻击,应用层有HTTP Flood、慢速攻击、CC攻击。每个层面都有对应的防御手段,但很少有团队能把每一层的基础防护都做扎实。多数情况是补上了网络层的洞,应用层又被打穿。
还有一点容易被忽略:DDoS经常被用作"烟雾弹"。攻击者先用大流量DDoS打乱运维的注意力,让所有人在带宽和CPU上疲于奔命,同时悄无声息地尝试其他更隐蔽的攻击方式,比如慢速SQL注入或业务逻辑漏洞利用。如果只盯着流量峰值看,很容易错过真正的威胁。安全领域的经典原则同样适用于这里——你防的不只是攻击本身,还有攻击背后的真实意图。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 常见攻击类型原理深度拆解
2.1 TCP SYN Flood:连接表耗尽型攻击的典型代表
SYN Flood 是历史最悠久、也最常见的DDoS手法之一。要理解它的原理,先回忆一下TCP三次握手:客户端先发SYN包,服务器收到后回复SYN+ACK,同时把这个半连接放进等待队列,客户端再回复ACK,连接建立,半连接出队。
问题就出在这个半连接队列上。操作系统内核给SYN队列分配的长度是有限制的,一旦队列堆满,新的正常请求就无法被处理。攻击者做的事情很简单:发送大量伪造源IP的SYN包,服务器回复SYN+ACK后等不到ACK确认,半连接只能一直挂在队列里等到超时。攻击者可以不断用新的SYN包刷新队列,让正常用户的所有新连接都进不去。
用生活化的类比来说,这就好比有人不停冲到餐厅前台假装要订座位,报一个假电话号码转身就走,前台服务员要把每个假订座记录在案,等回头确认时永远找不到人,真顾客打电话来订座的时候,登记表已经写满了。
针对SYN Flood的防御关键在两点:一是内核参数调优,改大SYN队列长度、开启SYN Cookie机制,诚实连接在握手阶段不占用队列资源;二是入口层面的过滤,把明显伪造源IP的流量清洗掉。单独靠哪一头都撑不住大流量,必须组合使用。
2.2 UDP反射放大攻击:低成本、高收益的攻击利器
UDP反射放大攻击在前几年非常流行,它的核心在于"放大效应"。某些UDP协议的服务(比如DNS、NTP)存在这样的特性:一个很小的请求包,能触发服务端返回一个大得多的响应包,而且服务端不验证源IP的真实性。
攻击者把请求包的源IP伪造为目标服务器的IP,然后把请求发给全球大量开放的UDP服务节点。这些节点会把放大后的响应包全部发到目标服务器。由于UDP本身没有握手和确认机制,服务端无法判断这个请求是不是真的来自目标,只能照单全收并回复。
举个例子,一个只有几十字节的DNS查询请求,可以触发几十倍甚至上百倍的响应数据。攻击者如果控制了足够多的伪造源发起查询,目标服务器将在完全不知情的情况下收到几十Gbps的垃圾UDP流量,带宽和CPU瞬间被打满。
这类攻击的防御思路和SYN Flood不太一样。靠源IP黑名单意义不大,因为源IP都是真实的UDP服务节点IP,黑名单切不过来。常规做法是在防火墙或清洗设备上直接限制非业务必需UDP端口的入站流量,比如DNS服务只允许访问自己的DNS端口,其余外部UDP一律丢弃。业务上如果确实需要暴露大量UDP端口,就要做好带宽冗余并配合专业清洗方案。
2.3 HTTP慢速攻击:不占带宽也能拖垮服务
慢速攻击是很多团队最容易忽视的一类DDoS,因为从带宽监控上看几乎毫无异常。它利用的是HTTP协议的一种特性:客户端可以慢慢发送请求数据。
以典型的Slowloris攻击为例。攻击者建立大量HTTP连接,发送请求头,但故意不发送完整的结束标志,或者以极低的速率一点点发送请求体。服务器收到不完整的请求后,会认为数据还在传输中,就一直保持这个连接不关闭。每个连接占用的资源不算多,但当攻击者建立了成千上万个这样的"僵尸连接"时,服务器的最大并发连接数就被耗尽,正常用户连TCP握手都无法完成。
识别慢速攻击比识别普通DDoS要难得多。流量总量不高,单看每个IP的请求速度都像正常用户,唯一的规律是连接建立后长时间占用不释放,而且请求进度总是卡在某一阶段。
防御慢速攻击比较有效的办法有三层:在Web服务器和负载均衡器上设置合理的请求超时时间和最大请求体大小;在接入层限制单IP的并发连接数;使用专业的WAF产品开启慢速攻击检测规则,自动断开长时间不完整的HTTP连接。参数设置要结合业务实际情况来权衡,不能一味调小超时时间导致正常上传场景被误伤。
2.4 CC攻击:应用层面的"千人千面"挑战
CC攻击(Challenge Collapsar的简称,也有人叫Challenge Control,指向应用层的HTTP Flood攻击)相比前几种更"聪明"。它模拟的不是畸形流量,而是极难识别的正常业务请求。攻击者控制的机器会像真实用户一样去访问首页、查询接口、搜索功能,甚至模拟登录流程。
更麻烦的是,CC攻击的流量分布极其分散。每个IP发起的请求频率可能只有每秒几次,从单个IP视角看完全正常,整体聚合起来却能把应用服务器的CPU和数据库连接打满。这就让传统基于频率的限流规则失效——如果你把单个IP的请求频率限制设得太严,正常用户在高并发场景下会被一起挡住。
应对CC攻击,关键的不是"堵",而是"识别和分流"。常见的手段包括:在应用层部署行为分析模块,识别请求的速度规律、User-Agent特征、访问路径深度等偏离真实用户的特征;对核心业务接口增加JS挑战或验证码机制,让攻击者脚本的自动化成本大幅上升;更彻底一点,在业务网关做全链路风控,引入设备指纹和IP信誉库,对高风险IP直接降级处理。
我个人的经验是,CC攻击没有一劳永逸的解决方案,它本质上是识别对抗的持续升级。你上了JS挑战,攻击者就把自动化浏览器改一改重新打;你用了设备指纹,他就去换更真实的伪造参数。真正有效的防御是建立多层检测:先靠边缘的规则和WAF快速过滤掉明显恶意的流量,再靠应用层的风控系统做精细化识别,确保攻击流量难以触达最核心的业务逻辑。
3. 防御策略设计:从入口到源站的三层防线
3.1 第一层:边缘接入与流量清洗
边缘接入层的核心任务只有一个:在流量还没有到达源站之前,就把攻击流量过滤掉。这一层是整个DDoS防御体系中投入产出比最高的部分,也是最容易被忽略的部分。
先说带宽冗余。明面上看,带宽是DDoS防御的第一道防线,但我不建议单纯靠这个思路。早年流行过"买5倍带宽扛攻击"的说法,但攻击流量峰值是不可预测的,10Gbps攻击你用50Gbps带宽扛住了,下一次遇到100Gbps呢?经济上不可持续。合理的做法是基础带宽冗余加流量清洗组合,冗余只用来应对短时冲击,清洗才是长期主力。
流量清洗的接入方式有两种:转发模式(牵引模式)和DNS引流模式。转发模式是把所有进入源站的流量先经过清洗设备,由设备识别并剔除攻击流量后再放行。DNS引流模式则是在攻击发生时,把域名的解析记录临时指向清洗服务商的高防IP,过滤后再通过隧道回源到真实服务器。前者适合规模较大的长期防护,后者更适合临时应急。
选用清洗方案的时候有几个关键考量点:清洗设备的处理能力决定了它能扛住多大峰值;清洗算法对正常流量的误判率直接关系到业务可用性;清洗链路本身的高可用性——清洗中心本身挂了怎么办,必须有备用链路。根据我接触过的案例,最稳妥的方案是主备双清洗链路,平时流量走主链路,检测到主链路异常时秒级切换。
3.2 第二层:服务器层面与内核参数调优
边缘清洗能挡住大部分网络层攻击,但总会有漏网的流量到达源站。这一层的目标是把服务器自身变成"打不死的小强",即便收到异常流量,核心业务进程也能保持稳定。
Linux服务器一项最重要的调优是TCP协议栈参数。下面是一份我在生产环境验证过的参数组合,可以作为基准参考:
bash复制# 提高SYN队列大小,减少半连接被丢弃的概率
net.ipv4.tcp_max_syn_backlog = 65536
# 开启SYN Cookie,让SYN Flood不占满半连接队列
net.ipv4.tcp_syncookies = 1
# 缩短SYN-ACK重传次数,快速回收异常连接
net.ipv4.tcp_synack_retries = 2
# 开启timewait复用,降低连接回收压力
net.ipv4.tcp_tw_reuse = 1
# 提高文件句柄和连接数上限
fs.file-max = 1000000
# 增大TIME_WAIT连接数上限
net.ipv4.tcp_max_tw_buckets = 2000000
几个参数的调优逻辑要讲清楚。tcp_syncookies开启后,服务器在SYN队列满时不再缓存半连接,而是通过计算一个加密序列号来验证后续ACK的合法性,这样攻击者的半连接根本进不了队列;tcp_synack_retries设小意味着服务器只重发两次SYN-ACK就断开,攻击者的大量无响应连接会被快速清理。
再往下是应用服务本身的连接和超时参数。以最常见的Nginx为例:
nginx复制worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
}
http {
# 客户端请求头超时时间,防止慢速攻击占用连接
client_header_timeout 10s;
# 客户端请求体超时时间,根据业务场景调整
client_body_timeout 10s;
# 响应超时时间
send_timeout 10s;
# 单个IP并发连接数限制
limit_conn_addr 10;
# 请求频率限制
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=20r/s;
}
注意这里的超时时间只是一个参考值。如果你的业务有大量正常的文件上传或长轮询请求,client_body_timeout不能设得太小。在调整参数前,务必做一次业务画像梳理——搞清楚正常用户的超时分布、并发分布数据,再去定参数,而不是拍脑袋写数字。
3.3 第三层:应用层限流与业务风控
应用层是整个防御体系里最讲究"精细活"的部分。网络层参数调好之后,服务器能扛住连接和带宽压力,但应用层的CPU和数据库连接仍然是暴露面。CC攻击打的就是这一块。
应用层限流的核心是区分"人"和"机器"。区分手段从轻到重排列,依次是:频率控制、请求特征校验、行为分析和人机验证。频率控制是最基础的,在Nginx或API网关上设置单IP、单账号的请求速率上限,超出就返回429或者直接丢弃。这个方式只能挡住最笨的脚本,稍微带点随机延迟的攻击者就能绕过去。
请求特征校验指的是检查HTTP头部的完整性。真实浏览器发出的请求通常带有Accept-Language、Referer等完整字段,而很多简单脚本只会发User-Agent和Host。但现在的攻击工具已经把这些特征模拟得很像,所以特征校验只能作为辅助手段。
真正有效的是行为分析。一个真实用户的访问路径通常是连续的:先打开首页,再看列表,然后点进详情;而攻击脚本只会死磕某一个接口。通过时序模型来识别用户的路径合理性,准确率会高很多。商业化的WAF在这块做得比较成熟,自研的话需要投入比较大的算法工程资源。
人机验证是最后的重型武器。常见形式有滑块验证、点选验证等。它的代价是有可能影响用户体验,所以一般只对高风险请求或者登录、下单等核心操作启用。在防御策略设计里,我一直坚持一个原则:不要把防线做成一道墙,而是要做成洋葱——每一层只挡住一部分攻击流,层层叠加之后,真正的恶性流量根本走不到最核心的业务逻辑。
4. 应急响应实操流程:被攻击时的生存指南
4.1 攻击识别与研判:先看清楚再动手
攻防对抗中最忌讳的就是"慌"。很多团队一发现流量异常,第一反应是重启所有服务或者把服务器都关机,这不仅解决不了问题,反而会让正常用户的体验更差。正确的第一步是冷静确认三件事:攻击目标是什么、攻击类型是什么、影响范围有多大。
攻击类型的判断可以依靠监控数据和抓包分析。如果带宽监控暴涨而CPU平稳,大概率是UDP Flood或者TCP Flood;如果带宽不高但连接数暴增,大概率是连接耗尽型攻击;如果带宽和连接数都平稳,但应用接口的响应时间急剧上升,那就是CC攻击或慢速攻击。用tcpdump或Wireshark抓几秒数据包,看包的大小分布、协议类型和源IP特征,判断会更快更准。
判断攻击类型的同时,要立刻梳理业务拓扑:哪些入口暴露在公网、业务是否依赖第三方API、核心数据存储有没有独立链路。很多团队在应急时最大的问题是根本不了解自己的业务依赖关系,清洗设备接上也怕误伤到正常请求,只能干等攻击结束。这个问题唯一解法是在平时就把资产清单摸清楚。
4.2 止血操作清单
确认攻击后,止血动作按优先级分几步执行。第一步是接入流量清洗。如果已经预置了清洗服务,直接切换引流;如果还没有,立刻联系服务商开通,这个操作正常情况下十分钟内可以完成。
第二步是在防火墙上做紧急过滤规则。网络层攻击通常特征明显:例如源IP来自某个持续发包的高风险网段、UDP端口大量访问非业务端口。防火墙规则宁可收紧一点,优先保稳定。这里给一份可以直接套用的iptables规则模板:
bash复制# 限制单个IP的最大并发连接数
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 100 -j DROP
# 丢弃非法端口的高频UDP流量
iptables -A INPUT -p udp -m state --state NEW -m limit --limit 5/s -j ACCEPT
iptables -A INPUT -p udp -m state --state NEW -j DROP
# 紧急封禁确认的攻击源IP段
iptables -A INPUT -s 203.0.113.0/24 -j DROP
第三步是当应用层被打穿时的快速策略。我会建议在Nginx上临时开启全局访问限速,并给核心接口加一层验证码。这样做会牺牲部分用户体验,但至少保证核心功能可用。同时把数据库连接池调低一些,防止连接被全部占满后数据库进程直接崩掉,恢复需要更长的时间。
第四步,同样关键,要做好攻击样本留存。把攻击流量抓包保存下来、记录时间线和响应动作,这些在事后溯源和调整防御方案时非常有用。很多团队打完一场仗就把数据删了,下次被攻击还得重新研判,所有复盘都无从谈起。
4.3 事后溯源与复盘
攻击结束后,很多人的第一反应是长舒一口气,然后把事情扔到一边。这是对成本的最大浪费。复盘的价值在于搞清楚三件事:攻击者的大概规模、攻击源的主要分布、以及现有防御暴露出来的薄弱环节。
溯源要基于日志、抓包和清洗设备的统计,分析攻击源的自治域和地理位置分布。虽然多数攻击源是受控的肉鸡,无法追溯到背后主使者,但可以看到攻击基础设施的规模。这些信息有助于评估后续攻击的风险等级,也能为购买高防带宽时提供数据依据。
防御薄弱环节的分析更重要。如果本次攻击是以CC为主,就要反思为什么WAF规则没拦住;如果是SYN Flood穿透了清洗设备,就要检查清洗链路的切换逻辑是否存在延迟。复盘输出应该是一份明确的整改清单,列出时间表、责任人和验收标准,把问题真正闭环掉。
5. 常见问题与排查技巧实录
5.1 防御投入的性价比误区
聊聊几个我在实践中特别常见的错误认知。
第一个误区是"高防IP买了就万事大吉"。高防IP只是把防御点前置,但很多攻击并不是针对IP本身,而是针对特定的业务域名或API接口。如果你把高防IP当作唯一防线,内部网络结构不隐藏,源站IP很容易通过子域名解析记录或者其他渠道泄露,攻击者一旦绕过清洗直接打源站,高防就变成了摆设。所以部署高防方案的前提是彻底隐藏源站,凡是能够解析到源站IP的所有历史记录和子域名都要做处理。
第二个误区是"所有流量都要洗"。清洗技术本质上是把流量先绕到第三方节点,再回注到源站,这个过程会引入额外的网络延迟。如果所有正常请求都经过清洗,业务性能一定受影响。合理的策略是只对高风险业务(登录、下单、核心API)做精细清洗,对静态资源或低风险请求走直连,把成本和性能损耗降到最低。
第三个误区是"防御规则设得越严越好"。很多团队在配置WAF规则时过于激进,频繁拦截了正常用户,尤其是偏远地区或者老旧浏览器的用户,UA特征和检测规则不匹配,误伤率居高不下。规则要在测试环境充分验证后再上线,上线后也要持续跟踪误报率数据,定期调整。
5.2 被误判为DDoS的另类情况
监控面板上流量突然飙升,不一定是被攻击了,也可能是业务自身的问题。有一次我处理过一个案例,某业务模块上线了数据同步任务,每小时定时从外部拉取一批大文件,带宽监控显示周期性尖峰,恰好和凌晨的一次攻击预警验证窗口重合,运维误判成DDoS,整个团队半夜做了无谓的应急启动。
所以看到流量异常的时候,除了按攻击处置,还要先检查是否存在这些可能性:业务模块上线了新的批处理任务,且没有限速;定时任务或数据备份集中在同一时间段执行;某个热门内容突然被大量分享引发瞬时洪峰。排除掉这些正常业务高峰,才能确定是攻击行为。
同理,在建设监控报警系统的时候,不要把单一指标作为触发条件。带宽、CPU、连接数和请求成功率多个指标联合告警,能大幅降低误报率。比如说带宽高但连接数低,且请求成功率正常,多半是正常大文件传输;带宽高、连接数高、请求成功率骤降,才更像是攻击状态。
5.3 团队协作与演练的重要性
最后说一个很多技术团队都容易忽略的点:DDoS防御不是一个技术问题,还是一个协作问题。涉及的团队通常包括运维、安全、应用开发、客服,甚至还有业务方。
洗牌操作需要网络权限,源站参数的调优需要运维配合,应用接口设置验证码需要开发配合,用户反馈和舆情监控需要客服支持。如果没有预案和分工,攻击发生时所有人都会涌向同一个群聊,既没有决策人也没有执行顺序,混乱程度甚至比攻击本身还严重。
建议每半年做一次DDoS防御演练,模拟攻击场景,从监控报警开始,走完整套研判、上报、清洗切换、源站加固的流程。演练中暴露出响应慢的环节、角色不清的地方、缺失的操作文档,都据此补齐。真实攻击发生时,团队执行的速度会显著提升。
防御这件事,很多时候考验的不是技术深度,而是平时准备的细致程度。
我个人做安全这么久,最大的体会是:DDoS防御没有一劳永逸的银弹,攻击手法在变,业务形态在变,防御方案必须跟着持续演进。但有一些底层的功课是永远值得做扎实的:资产底数摸清楚、防御链路提前搭好、应急流程反复演练、每次攻击之后认真复盘。把这些基础打牢,无论攻击从哪个方向来,你都会有底气接住。
针对这套方案,大家如果有更具体的场景问题,比如业务量级不同、技术栈不同时防御策略怎么调整,欢迎在评论区把你的情况写下来,我针对具体场景帮忙出主意。
