进程网络带宽限制脚本防止恶意占满带宽
问题:单进程把带宽吃满怎么办
当服务器上某个脚本、程序或恶意进程突然占满网络带宽,其他正常服务会瞬间变慢甚至无法访问。
常见的场景包括被植入挖矿病毒、爬虫过度抓取、或者有 Bug 的程序无限下载。
直接杀掉进程可能影响业务,更合理的做法是对指定进程做网络带宽限制。
下面介绍一套基于 iptables + tc 的脚本方案,可让零基础用户也能快速实现单进程精准限速。
准备:你需要什么环境和工具
- 一台 Linux 服务器(CentOS 7/8、Ubuntu 18.04+ 均可),有 root 权限。
- 必备工具:
iptables、tc、iproute2。一般系统自带,未安装的可以执行yum install iptables-services iproute-tc(CentOS)或apt install iptables iproute2(Ubuntu)。 - 一个要被限速的测试进程:比如用
dd if=/dev/zero of=/dev/null &模拟,实际场景中是你要控制的目标程序。 - 建议先熟悉基础命令
pgrep、ps、htop,用来定位进程 PID。
核心步骤:编写进程带宽限制脚本
原理:先给进程指定一个专属 Linux 用户,再通过 iptables 的 -m owner --uid-owner 匹配该用户的所有网络包,最后用 tc 对这些包做限速。
这样同一个用户下的所有进程(包括子进程)都会被限速,无需逐 PID 配置。
1. 创建专用限速用户
useradd -s /sbin/nologin limit_user
将你要限制的程序以 limit_user 运行,例如:
su -s /bin/bash limit_user -c "/path/to/your/program"
如果你已经有一个正在运行的进程,可以先暂停并改用 limit_user 启动。
2. 编写限速脚本 limit_bandwidth.sh
#!/bin/bash
# 限制用户 limit_user 的所有网络流量,下行 1Mbps,上行 500Kbps
# 接口名称请根据实际修改,比如 eth0 或 ens3
IFACE="eth0"
UID="limit_user"
DOWNLINK="1mbit"
UPLINK="500kbit"
# 清除原有规则(谨慎操作)
tc qdisc del dev $IFACE root 2>/dev/null || true
iptables -t mangle -F 2>/dev/null || true
# 创建根队列
tc qdisc add dev $IFACE root handle 1: htb default 30
# 创建限速类
tc class add dev $IFACE parent 1: classid 1:1 htb rate $DOWNLINK ceil $DOWNLINK
tc class add dev $IFACE parent 1: classid 1:2 htb rate $UPLINK ceil $UPLINK
# 添加 iptables 标记规则(匹配 limit_user 用户)
iptables -t mangle -A OUTPUT -m owner --uid-owner $UID -j MARK --set-mark 10
iptables -t mangle -A INPUT -m owner --uid-owner $UID -j MARK --set-mark 11
# 将标记为 10 的包(上行)归到 class 1:2,标记为 11 的包(下行)归到 class 1:1
tc filter add dev $IFACE parent 1: protocol ip prio 1 handle 10 fw flowid 1:2
tc filter add dev $IFACE parent 1: protocol ip prio 1 handle 11 fw flowid 1:1
echo "已限制用户 $UID 的网络带宽:上行 $UPLINK,下行 $DOWNLINK"
3. 运行脚本并验证
chmod +x limit_bandwidth.sh
./limit_bandwidth.sh
立即生效。
如果测试进程正在运行,网速会被压制到指定值。
可以用 nethogs 或 iftop 实时观察流量变化。
避坑指南与常见问题
- 重启后规则失效:需要将脚本加入开机自启,例如在
/etc/rc.local中调用bash /path/to/limit_bandwidth.sh。 - uid-owner 不起作用:确认 iptables 的 owner 模块已加载(
lsmod | grep xt_owner),CentOS 7 默认支持。如果输出为空,执行modprobe xt_owner。 - 限速不生效:检查接口名称
IFACE是否正确(可用ip link show查看)。另外注意 tc 与 iptables 的版本兼容性,建议用最新内核。 - 只想限速某个 PID 而不是整个用户:可以配合 cgroups v2 的
net_cls子系统,但配置更复杂,新手建议先使用用户隔离方法。 - 如何恢复无限制:执行
tc qdisc del dev eth0 root并清空 iptables mangle 表:iptables -t mangle -F。
效果验证与扩展建议
- 用
dd测试:在 limit_user 下运行dd if=/dev/zero of=/dev/null本应占满带宽,但观察实际速率不超过设定值。 - 用
nethogs监控:nethogs eth0,能看到该进程的流量被压制。 - 调整限速值:修改脚本中的
DOWNLINK和UPLINK单位(可用 kbit、mbit),重新执行即可生效。
这套脚本适合小白直接套用,也适合作为高级限速的基础模板。
如果你需要更精细的控制(比如基于时间、访问目的 IP),可以在 iptables 标记部分添加更多匹配条件。
记住:先隔离用户,再限制流量,是最稳妥的进程带宽管理方式。