DDoS攻击下网络拥塞的核心问题,不在于你能挡住多少流量,而在于你怎么控制TC(Traffic Control)流量调度和队列规则来做精准限速。说白了,面对海量攻击流量,单纯靠防火墙硬扛是扛不住的,必须在Linux内核层面用TC工具对入站流量做分级、排队、限速、丢弃,把有限的带宽资源分配给正常业务流量,同时把攻击流量压制在可控范围内。这套机制的本质就是:不是消灭所有流量,而是让正常流量活下来,让异常流量排队等死或者被提前丢弃。

要理解这套体系,首先得搞清楚三个关键概念:TC是什么、队列规则怎么工作、限速防拥塞的具体策略。TC是Linux内核自带的流量控制子系统,它通过qdisc(队列规则)和class(类)来实现对网络数据包的精细化管理。你可以把它想象成一个高速公路的收费站加匝道系统——不同类型的车走不同车道,超速的车被拦下来,车道满了就不让进。DDoS防护场景下,我们就是要用这套系统把攻击流量和正常流量分开处理,确保核心业务不被淹没。

TC流量控制的核心架构:根qdisc、class与filter

TC的工作层级是从网卡根节点开始的。你在网卡上挂载一个根qdisc,通常用HTB(Hierarchical Token Bucket,层次令牌桶)或者HFSC。HTB是最常用的,因为它支持分层限速,可以给不同类型的流量设置不同的带宽上限和优先级。在HTB下面,你可以创建多个class,每个class代表一类流量,比如正常HTTP流量、DNS流量、SYN洪水流量等等。然后通过filter规则把数据包分类到对应的class里。整个结构就像一棵树,根节点控制总带宽,子节点控制各分支的分配。

具体操作上,你先给网卡eth0挂载根qdisc:

tc qdisc add dev eth0 root handle 1: htb default 999

这条命令的意思是:在eth0上创建一个HTB根队列,默认class编号是999(通常用来放未分类的流量,也就是攻击流量)。然后你创建父class和子类:

tc class add dev eth0 parent 1: classid 1:1 htb rate 500mbit ceil 800mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 300mbit ceil 500mbit prio 1
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 100mbit ceil 200mbit prio 2
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 50mbit ceil 100mbit prio 3

这里1:1是父class,总带宽500M到800M;1:10、1:20、1:30是三个子class,分别给高、中、低优先级流量。prio值越小优先级越高,高优先级的class会优先获得带宽。剩下的默认999 class就是用来兜底攻击流量的。

队列规则限速的关键:令牌桶机制与突发控制

HTB的限速核心是令牌桶算法。每个class有两个参数:rate(承诺速率)和ceil(最大速率)。rate是保证带宽,ceil是突发上限。当流量低于rate时,令牌桶积累令牌;当流量超过rate但低于ceil时,可以借用令牌;超过ceil就直接丢弃。这个机制特别适合DDoS防护,因为正常业务流量通常比较平稳,而攻击流量是突发的。你给正常业务设一个合理的rate保证它永远有带宽,给攻击流量的class设一个很低的rate甚至直接用sfq或pfifo让它排队然后丢弃。

另外一个重要的队列规则是RED(Random Early Detection,随机早期检测)。RED不是等队列满了才丢包,而是在队列达到一定阈值时就开始随机丢弃数据包。这样做的好处是避免TCP全局同步——如果所有TCP连接同时检测到丢包然后同时减速,网络会剧烈震荡;随机丢弃让不同连接在不同时间减速,网络更平稳。在DDoS场景下,RED配合HTB使用效果非常好:

tc qdisc add dev eth0 parent 1:10 handle 10: red limit 60000 min 15000 max 45000 avpkt 1000 burst 50 probability 0.4

这条命令在1:10这个class下面挂了一个RED队列,limit是队列最大长度,min和max是开始丢弃和最大丢弃的阈值,avpkt是平均包大小,burst是突发容忍量,probability是最大丢弃概率。当队列长度在15000到45000之间时,RED开始按概率丢包,超过45000就全丢。

用filter规则精准分类流量:把攻击流量和正常流量分开

光有队列和限速还不够,你得告诉TC哪些包是正常的、哪些是攻击的。这就需要filter规则。常用的分类依据包括:源IP、目的IP、源端口、目的端口、协议类型、包大小、TCP标志位等。在DDoS防护中,最实用的分类策略是基于流量特征:比如SYN包占比异常高的就是SYN洪水,小包占比高的可能是UDP洪水,特定目的端口的可能是应用层攻击。

下面是一个基于iptables标记配合TC filter的实战例子。先用iptables给异常流量打标记:

iptables -t mangle -A PREROUTING -p tcp --syn -m limit --limit 1000/sec -j MARK --set-mark 10
iptables -t mangle -A PREROUTING -p udp --dport 53 -m limit --limit 500/sec -j MARK --set-mark 20
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j MARK --set-mark 99

然后用TC的fw classifier根据mark值分类:

tc filter add dev eth0 parent 1:0 protocol ip handle 10 fw classid 1:10
tc filter add dev eth0 parent 1:0 protocol ip handle 20 fw classid 1:20
tc filter add dev eth0 parent 1:0 protocol ip handle 99 fw classid 1:999

这样,被标记为10的SYN流量进入高优先级class,被标记为20的DNS流量进入中优先级,其他所有(包括攻击流量)进入默认999 class被限速或丢弃。这套组合拳是DDoS防护中最经典的做法。

防拥塞的进阶策略:多层级联与动态调整

实际生产环境中,DDoS攻击的类型和规模是动态变化的。静态规则往往不够用,你需要多层级联和动态调整能力。所谓多层级联,就是在HTB下面再套HTB或者其他qdisc(如SFQ、TBF),形成更细粒度的控制。比如在攻击流量的999 class下面再挂一个TBF(Token Bucket Filter)做二次限速:

tc qdisc add dev eth0 parent 1:999 handle 999: tbf rate 10mbit burst 32kbit latency 50ms

这样即使攻击流量进入了999 class,也最多只能用10M带宽,其余全部被内核层面直接丢弃,不会占用更多系统资源。latency参数控制了令牌桶的延迟特性,值越小丢弃越激进。

动态调整方面,可以用脚本监控流量并实时修改TC规则。比如写一个shell脚本每5秒检查一次网卡流量,如果检测到某类流量超过阈值就自动调整对应class的rate:

#!/bin/bash
while true; do
    CURRENT=$(tc -s class show dev eth0 | grep "1:10" | awk '{print $2}')
    if [ "$CURRENT" -gt 400000000 ]; then
        tc class change dev eth0 parent 1:1 classid 1:10 htb rate 200mbit
    fi
    sleep 5
done

这个脚本监控1:10 class的当前速率,如果超过400M就降到200M,把多余带宽让给其他class。当然生产环境中要更精细,需要结合具体业务SLA来设定阈值。

实际部署中的注意事项和常见坑

第一,TC规则是有顺序的,先匹配的规则优先执行,所以filter规则的顺序很重要,要把最精确的匹配放前面。第二,HTB的rate单位是bit/s,别搞混成byte/s,否则限速会差8倍。第三,不要在高流量网卡上挂太多复杂规则,TC本身也消耗CPU,规则太多会导致内核处理不过来反而加剧拥塞。第四,一定要保留SSH管理端口的流量不被误限,否则你把自己锁在外面就尴尬了——可以在filter里加一条白名单规则优先匹配管理IP。

第五,TC只能做入站流量控制,对于出站方向的DDoS(比如你的服务器被利用做反射攻击),需要在出站方向也部署类似规则。第六,TC不是万能的,它解决的是带宽层面的拥塞控制,对于应用层CC攻击(比如大量合法HTTP请求),需要配合WAF、频率限制等更上层的防护手段。TC是底层防线,不是唯一防线。

总结:TC流量控制是DDoS防护的底层基石

DDoS防护是一个多层体系,从网络层到应用层都要有对应策略。TC流量控制和队列规则限速是网络层最硬核的手段,它直接在内核层面调度数据包,不依赖任何用户态程序,性能损耗极低,响应速度极快。掌握HTB分层限速、RED随机早期检测、fw classifier标记分类、TBF二次限速这些核心技术,你就能在面对大规模流量攻击时保住核心业务的可用性。关键不是挡住所有攻击,而是在有限资源下做出最优的流量分配决策——这才是防拥塞的真正含义。