利用 tc+iptables 对 Linux 进行端口限速

由 三硝基豆腐 发布

这么简单个问题,在我想象中应该就是这么一句话的事情:

对网卡 eth0 端口 *** 限速——上行速度***,下行速度***

然而我发现是我年轻了。

网上的教程一个比一个牛逼,我连着看了3个教程(这里就不点名了):

  • 第一个:把classid写成calssid
  • 第二个:linux 命令tc写成Tc
  • 第三个:注释中说网卡是 eth0,命令里却是 ens8
  • 第四个:代码明明把速度限制成了 1Mbps,却睁着眼睛说瞎话:限制成 2Mbps

大家有兴趣可以去把这些播主搜出来,他们大概是有帕金森,要不就是白内障,挺可怜的,咱们也捐点钱给他们吧。

行了说正事。

系统环境

Ubuntu 16.04 64位(服务器),安装了 iptables 和 tc(没有的可以 apt install 一下),ufw 和 firewalld 均未启用。

请尽量保证你的 tc 和 iptables 像我的一样纯净,如果产生冲突可能会导致失败。

所有操作于 2020 年 1 月 29 日执行。

临时限速

直接执行以下代码可对20000号端口进行限速,网卡名eth0,限速至2Mbps,限制将在系统重启后失效。

说明:

  1. 第二行的rate1:1这个class的总带宽
  2. 第三行的rate1:10这个class的带宽(1:101:1的子类)
  3. 第三行的ceil1:10这个class最大带宽,必须大于等于2.中所说的rate且小于等于1.中所说的rate
  4. 如果你嫌麻烦,就把上面三个值都设为你想设定的带宽就行了
tc qdisc add dev eth0 root handle 1:0 htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 2Mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 2Mbit ceil 2Mbit
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 10 fw classid 1:10
iptables -A OUTPUT -t mangle -p tcp --sport 20000 -j MARK --set-mark 10

永久限速

为防止重启失效,将上面的那段代码放入/etc/rc.local中即可,开机时将会自动执行。

/etc/rc.local中默认有一行exit 0,请将代码放在该行前面。


仅有一条评论

  1. 三硝基豆腐
    三硝基豆腐 · 2020-01-29 07:51 作者

    更新:
    经测试,似乎 ufw 对该方法无影响
    而 firewalld 会导致该方法失效
    具体原因并未深究

发表评论