为10万个WireGuard节点扩展流量控制(tc)以实现带宽限制
老哥,我太懂你这个痛点了——要给10万个WireGuard节点做10Mbps的带宽限制,试了tc的hfsc、htb,规则数量一上去就失效,这搁谁都头疼。你之前想到用nftables打标记减少tc规则的方向完全是对的,但遇到同标记流量共享带宽的问题,其实是没搭配对合适的调度器。结合你的场景,我给你两个落地性极强的方案,尤其是第一个,几乎零配置就能搞定10万节点的需求:
方案一:用Cake QDisc直接实现单节点限速(强烈推荐,适合所有peer限速相同的场景)
Cake是Linux内核里专门为高并发、公平调度设计的QDisc,自带per-host(按源IP隔离)的功能,完美匹配你“每个WireGuard peer限10Mbps”的需求,而且不需要写一堆tc filter或者nftables规则,一条命令就能搞定,性能开销极低,完全能扛住10万节点的规模。
具体操作:
- 先清理wg0接口上旧的tc规则(如果有的话):
tc qdisc del dev wg0 root
- 配置Cake QDisc:
tc qdisc add dev wg0 root cake bandwidth 1000mbit per-host isolate host bandwidth 10mbit
参数解释:
bandwidth 1000mbit:设置wg0接口的总带宽上限,根据你的服务器实际出口带宽调整(比如服务器是2G出口就设2000mbit)per-host isolate host:开启按源IP(每个WireGuard peer)隔离流量的模式bandwidth 10mbit:给每个单独的主机(peer)设置带宽上限为10Mbps
这样配置后,每个WireGuard peer的带宽都会被限制在10Mbps,而且互相之间不会抢占带宽,Cake会自动用哈希表管理所有节点的流量,内存和CPU开销比传统tc规则低几个量级。
方案二:nftables标记分组 + TC HTB + Cake(适合存在多带宽需求的场景)
如果以后你需要给不同peer设置不同带宽(比如部分10Mbps、部分100Mbps),可以用nftables按带宽分组打标记,再配合TC HTB和Cake实现分组内的单节点限速,这样能大幅减少tc规则的数量:
步骤1:用nftables给不同带宽组的peer打标记
假设你把10Mbps的peer放在10.0.0.0/24子网,100Mbps的放在10.0.1.0/24子网:
# 创建mangle表和自定义链 add table ip mangle add chain ip mangle wg_mark { type filter hook prerouting priority mangle; policy accept; } # 给10Mbps的peer打标记0x1 add rule ip mangle wg_mark iifname "wg0" ip saddr 10.0.0.0/24 meta mark set 0x1 # 给100Mbps的peer打标记0x2 add rule ip mangle wg_mark iifname "wg0" ip saddr 10.0.1.0/24 meta mark set 0x2
步骤2:配置TC HTB根队列和分组Class
# 清理旧规则 tc qdisc del dev wg0 root # 添加HTB根队列 tc qdisc add dev wg0 root handle 1: htb default 10 # 为10Mbps组创建Class,并搭配Cake实现单节点限速 tc class add dev wg0 parent 1: classid 1:1 htb rate 1000mbit ceil 1000mbit tc qdisc add dev wg0 parent 1:1 cake bandwidth 1000mbit per-host isolate host bandwidth 10mbit # 为100Mbps组创建Class,并搭配Cake实现单节点限速 tc class add dev wg0 parent 1: classid 1:2 htb rate 500mbit ceil 500mbit tc qdisc add dev wg0 parent 1:2 cake bandwidth 500mbit per-host isolate host bandwidth 100mbit
步骤3:把标记流量映射到对应Class
tc filter add dev wg0 parent 1: protocol ip prio 1 handle 0x1 fw flowid 1:1 tc filter add dev wg0 parent 1: protocol ip prio 1 handle 0x2 fw flowid 1:2
这样配置后,不同带宽组的流量会进入对应的Class,每个Class内的Cake会自动给每个peer分配对应的带宽上限,既解决了规则数量过多的问题,又支持多带宽需求。
注意事项:
- 确保你的Linux内核版本在4.19及以上,Cake QDisc是从这个版本开始内置的,如果内核版本过低,可以升级内核或者编译对应的模块。
- 测试时先用少量peer验证带宽限制是否生效,比如用iperf3测试单个peer的上行/下行带宽是否稳定在10Mbps,再用多个peer同时测试是否互相不影响。
备注:内容来源于stack exchange,提问作者Saad Ahmed

