iptables负责标记流量,tc执行限速;iptables在mangle表用--set-mark打标,tc通过htb等队列规则按标记实施带宽、突发与优先级控制。

Linux 实现流量控制与限速,iptables 不直接限速,只负责标记流量;真正执行带宽限制的是 tc(Traffic Control)。两者必须配合使用:iptables 在 mangle 表中打 MARK,tc 根据标记将流量导入不同限速类(class),再通过队列规则(如 HTB)实施速率、突发、优先级等控制。
一、明确角色分工:谁干啥
-
iptables 是“识别员”
匹配源 IP、目标 IP、端口、协议等条件,用--set-mark给数据包贴标签(如--set-mark 100)。
只在mangle表中操作,常用链为:-
POSTROUTING:用于本机发出的上行流量(如服务器对外提供服务时的响应包) -
PREROUTING:用于进入本机的下行流量(如客户端访问服务器时的请求包)
-
tc 是“执行员”
在网卡出口(egress)建立队列(qdisc),划分限速类(class),再用 filter 把 iptables 打的 mark 映射到对应 class。
⚠️ Linux 原生不支持对入站(ingress)流量直接限速,需借助 ifb 虚拟设备间接实现。
二、典型出口限速配置(以 eth0 上行限速为例)
假设要限制内网用户 192.168.1.100 的上行总带宽为 1Mbps:
# 1. 清理旧规则(避免冲突) tc qdisc del dev eth0 root 2>/dev/null iptables -t mangle -F # 2. 创建 HTB 根队列(handle 1:,默认走 class 1:30) tc qdisc add dev eth0 root handle 1: htb default 30 # 3. 创建根类(保证总出口能力,留余量) tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit # 4. 创建子类(专限该用户上行) tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1mbit ceil 1mbit # 5. 绑定公平队列(防单连接占满带宽) tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10 # 6. iptables 打标(注意链选 POSTROUTING,因是本机发出的上行包) iptables -t mangle -A POSTROUTING -s 192.168.1.100 -j MARK --set-mark 100 # 7. tc filter 关联:mark 100 → class 1:10 tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 100 fw flowid 1:10
✅ 验证是否生效:
tc -s class ls dev eth0查看各 class 流量统计iptables -t mangle -L -v -n看 pkts 列是否增长tc -s qdisc ls dev eth0检查队列状态
三、按端口或应用限速(更灵活匹配)
只需调整 iptables 的匹配条件,其他 tc 步骤不变:
-
限制所有发往 Web 端口(80/443)的下行响应流量为 5Mbps:
linux-performance-analyzer下载Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
iptables -t mangle -A POSTROUTING -p tcp -m multiport --dports 80,443 -j MARK --set-mark 200 tc class add dev eth0 parent 1:1 classid 1:20 htb rate 5mbit ceil 5mbit tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 200 fw flowid 1:20
-
限制某客户端
192.168.1.200访问10.0.0.5:3306(MySQL)的上行请求流量为 200Kbps:iptables -t mangle -A POSTROUTING -s 192.168.1.200 -d 10.0.0.5 -p tcp --dport 3306 -j MARK --set-mark 300 tc class add dev eth0 parent 1:1 classid 1:30 htb rate 200kbit ceil 200kbit tc filter add dev eth0 protocol ip parent 1:0 prio 3 handle 300 fw flowid 1:30
四、入站流量限速(需 ifb 虚拟设备)
Linux 无法直接限 ingress,但可通过 ifb 将入站包“重定向为伪出站”,再用 tc 控制:
# 1. 加载模块并启用 ifb0 modprobe ifb numifbs=1 ip link set dev ifb0 up # 2. 用 iptables 将目标入站包重定向到 ifb0(PREROUTING) iptables -t mangle -A PREROUTING -d 192.168.1.100 -j FORWARD iptables -t mangle -A FORWARD -o ifb0 -j ACCEPT iptables -t mangle -A PREROUTING -d 192.168.1.100 -j ACTION_REDIRECT_TO_IFB # 更标准写法(需配合 tc redirect): # 先标记,再用 tc action mirred 重定向(进阶用法,此处略) # 推荐直接参考:tc qdisc add dev ifb0 root htb default 10 + 后续 class/filter
? 提示:ifb 方案稍复杂,生产环境建议优先从出口(POSTROUTING)角度设计策略,多数 QoS 场景可覆盖。
五、持久化与维护要点
- 重启后规则丢失,需保存并开机加载:
iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu tc qdisc show dev eth0 > /etc/tc/eth0.qdisc # 自定义脚本恢复
- 写成启动脚本(如
/usr/local/bin/qos-start.sh),加入systemd或rc.local - 避免误用
-m limit:它只控包速率(如每秒最多 10 个 SYN),不是带宽限速 -
ceil值设为等于rate可禁用带宽借用,确保严格上限;设更大则允许突发
不复杂但容易忽略细节。










