限制网络速率,但允许每个TCP连接突发,然后限制


8

我们有一个Cisco路由器,它允许速率限制(他们称其为管制),但允许在每个TCP连接的基础上爆发。例如,我们可以将带宽限制为50兆位,但是直到传输4兆字节时才会施加该限制。这是对每个建立的TCP连接强制执行的。

在Linux中有什么方法可以做到这一点吗?此外,这种解决方案是否有任何弊端?如果对任何人都有用,则用于设置突发的Cisco命令是根据策略映射(至少在我们的ASA 5505上)运行的Police命令的第三个参数。

这样做的目的是允许服务器利用95/5突发事件并为普通用户尽快提供网页服务,但减少超过5%的时间突发事件的可能性(例如,如果使用服务器对服务器进行操作)传输或从网站下载大文件)。我了解DDoS攻击持续的时间太长了,这可能不是解决方案,但是由于各种原因,在这里不必担心。

Answers:


6

这在Linux中可以通过iptables和来实现tc。您可以将iptables配置为MARK已传输一定数量字节的连接上的数据包。然后tc,您可以将这些标记的数据包放在排队规则的类中,以对带宽进行速率限制。

有点棘手的部分是限制上载和下载的连接。tc不支持入口流量整形。您可以通过在面向Web服务器的界面上调整出口(这将对下载到您的Web服务器的形状)进行整形,并在面向上游提供者的界面上调整出口(将对从Web服务器的上传进行整形)来解决此问题。由于您无法控制上游提供商发送数据的速度,因此您并没有真正在影响入口(下载)流量。但是,对面向Web服务器的界面进行整形将导致数据包丢失,并且上传程序会缩小其TCP窗口以适应带宽限制。

示例:(假设这是在基于Linux的路由器上,面向接口的Web服务器是eth0,上游是eth1

# mark the packets for connections over 4MB being forwarded out eth1
# (uploads from webserver)
iptables -t mangle -A FORWARD -p tcp -o eth1 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50

# mark the packets for connections over 4MB being forwarded out eth0
# (downloads to webserver)
iptables -t mangle -A FORWARD -p tcp -o eth0 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50

# Setup queuing discipline for server-download traffic
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:50 htb rate 50mbit

# Setup queuing discipline for server-upload traffic
tc qdisc add dev eth1 root handle 1: htb
tc class add dev eth1 parent 1: classid 1:50 htb rate 50mbit

# set the tc filters to catch the marked packets and direct them appropriately
tc filter add dev eth0 parent 1:0 protocol ip handle 50 fw flowid 1:50
tc filter add dev eth1 parent 1:0 protocol ip handle 50 fw flowid 1:50

如果您想在网络服务器本身而不是在Linux路由器上执行此操作,则仍然可以使用上述内容的上载部分。一个值得注意的变化是您将替换FOWARDOUTPUT。要进行下载,您需要使用“中间功能块”设备或来设置排队规则ifb。简而言之,它使用虚拟接口,因此您可以将入口流量视为出口,并使用从此处进行调整tc。有关如何设置的更多信息,请ifb参见:https//serverfault.com/questions/350023/tc-ingress-policing-and-ifb-mirroring

请注意,这种类型的内容往往需要大量调整才能缩放。迫在眉睫的是connbytes依赖conntrack模块,它往往会碰到带有大量连接的缩放壁。我建议进行重负载测试。

另一个警告是,这对于UDP根本不起作用,因为它是无状态的。还有其他技术可以解决此问题,但看起来您的要求仅针对TCP。

另外,要撤消上述所有操作,请执行以下操作:

# Flush the mangle FORWARD chain (don't run this if you have other stuff in there)
iptables -t mangle -F FORWARD

# Delete the queuing disciplines
tc qdisc del dev eth0 root
tc qdisc del dev eth1 root
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.