如何在 Linux 中限制每个用户的上传带宽?

如何在 Linux 中限制每个用户的上传带宽?

有人可以提供tc在 Debian Lenny 中限制每个用户上传带宽的命令吗?

我发现要使用 iptables 标记每个用户的数据包,我可以使用以下命令

iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner testuser -j MARK --set-mark 500

但我不知道如何使用tc

更新

通过运行以下命令,我成功将测试用户的上传带宽限制为 10Mbit

iptables -t mangle -N HTB_OUT
iptables -t mangle -I POSTROUTING -j HTB_OUT
iptables -t mangle -A HTB_OUT -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -m owner --uid-owner testuser -j MARK --set-mark 10

tc qdisc replace dev eth0 root handle 1: htb default 30
tc class replace dev eth0 parent 1: classid 1:1 htb rate 10Mbit burst 5k
tc class replace dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit ceil 10Mbit
tc qdisc replace dev eth0 parent 1:10 handle 10: sfq perturb 10
tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10

现在的问题是,我不想限制测试用户的 FTP 带宽,但通过运行上述命令,FTP 速度也限制为 10Mbit。

问候

答案1

我发现您的 htb 配置有几个明显的问题。

首先,您没有 1:30 句柄,而您应该有,因为default 30。也许您的意思是default 1?这会将所有流量附加到 classid 1:1,除非规则将流量附加到不同的类。

其次,您需要将 htb 1:1 最高级别类中的速率设置为合理的值,并且低于您的线路速率。例如,如果您的线路速率为 100Mbit,速率应该为 90%:90Mbit。有些人建议更保守的设置,如 75% 的线路速率;我以 90% 的速率玩危险游戏,对我来说效果不错 - 如果您注意到丢包或带宽分配不当,请降低。后者表示上行缓冲。

第三,您的速率限制类应配置为一个rate设置为您愿意为该类分配的保证带宽,并将ceil设置为您允许用户的最大级别。例如,假设您想为 testuser 提供 400kbit 的保证带宽,但如果线路处于空闲状态,则让它增长到线路速率。将rate 400kbitceil 设置为您作为 1:1 的速率设置的任何值。如果您不设置 ceil,则默认为速率。

第四,为了实现豁免 ftp 流量的目标,您需要使用 connmark 而不是 mark。否则,您的相关数据连接将无法正确获得 --set-mark 10 的豁免。Connmark 将正确拾取相关连接。

我建议遵循以下(未经测试的!)规则:

# flush rules out of postrouting so you're not constantly inserting during testing.
iptables -t mangle -F POSTROUTING
iptables -t mangle -X HTB_OUT

# The use of RETURN here is to fall out of our user chain and hit 
# -j CONNMARK --save-mark in the POSTROUTING chain.
iptables -t mangle -N HTB_OUT
iptables -t mangle -A HTB_OUT -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -p tcp --dport 21 -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -m mark ! --mark 0 -j RETURN
iptables -t mangle -A HTB_OUT -m owner --uid-owner testuser -j MARK --set-mark 10
iptables -t mangle -A HTB_OUT -m mark ! --mark 0 -j RETURN

iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A POSTROUTING -j HTB_OUT
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

然后对于 tc,类似以下内容:

# set a script variable that will represent our line-rate minus some change
CAPRATE=90Mbit
CAP_SUB_400=89Mbit

# clear our qdisc settings for eth0 so we're starting from a clean slate.
tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:1 htb rate ${CAPRATE} burst 5k
# this is our capped class:
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 400kbit ceil ${CAPRATE}
# this is our default, catch-all class:
tc class add dev eth0 parent 1:1 classid 1:20 htb rate ${CAP_SUB_400} ceil ${CAPRATE}
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10

tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10

要记住的事情:任何父级的直系子级的总和rate都不应超过父级rate。我在这里作了一点小手脚,将 1:20 的速率四舍五入为 89Mbit,而不是 89600kbit。您可以承诺不足,但绝不能承诺过度。

评估 iptables 规则为了如果您的策略允许,最常见的匹配应该首先出现;在进入 HTB_OUT 链之前,POSTROUTING 规则可以消除大部分这种情况,但这是一个很好的经验法则。

那么 SFQ 是用来做什么的呢?它就像搅动锅一样。SFQ 尝试为每个连接(实际上是端点对)分配公平的带宽份额,然后每隔一秒它就会再次混合,以防太多连接最终进入同一个内部存储桶(这是可能的,因为 src/dst/portpair 上的哈希处理方式)。有关更多信息,请查看 lartc 或 tc-sfq 手册页。

答案2

iptables -A OUTPUT -m conntrack --connbytes from:to --connbytes-mode packets/bytes/avgpkt -m owner --uid-owner owner -J DROP

其他可能性-m connlimit -m hashlimit

相关内容