使用 tc 过滤器和 u32 匹配限制给定端口的输入

使用 tc 过滤器和 u32 匹配限制给定端口的输入

我正在尝试限制端口 8128-8191 上的所有传入流量。我已阅读了所有发现的内容,检查了所有内容十遍,但仍然不起作用。

命令:

tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1kbit ceil 1kbit
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 match ip dport 8128 0xFFC0 classid 1:1  

这是我计算面具的方法:

expected = lowest port  = 0b_0001_1111_1100_0000 = 0x1FC0 = 8128d
    mask = highest port = 0b_1111_1111_1100_0000 = 0xFFC0 
           highest port = 0b_0001_1111_1111_1111 = 0x1FFF = 8191d

输出:

#tc -s class show dev eth0
class htb 1:1 root prio 0 rate 1000bit ceil 1000bit burst 1600b cburst 1600b
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 lended: 0 borrowed: 0 giants: 0
 tokens: 200000000 ctokens: 200000000

# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
  match 00001fc0/0000ffc0 at 20

我从我的工作站发送字节流:

cat /dev/urandom | pv -L 3k | nc -nvv ${SERVER_ADDRESS} 8128

在服务器上我接收它们:

nc -nvvl -p 8128 > /dev/null

我使用优秀的 iptraf 检查了 eth1 的使用情况,吞吐量仍然停留在 3 kbit/s 及以上,并且计数器没有增加class htb 1:1

我相信自己能很好地使用面膜。我也尝试过一些更简单的方法,但dport 8128 0xFFFF没有效果。

显示过滤器时,at 20似乎正确,因为 IP 标头长度为 20 字节。源端口和目标端口是前 4 个字节,因此 32 位匹配是正确的。我不明白其他值。

我正在使用 Debian 7:

# uname -a
Linux node-1 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u5 x86_64 GNU/Linux

我也清除在尝试上述操作之前,请先检查 iptables 中的所有内容。

也许我在将过滤器连接到类时搞砸了某些事情。也许我忘记激活某些内核选项了。

有什么见解吗?

答案1

1)tc使用标准 Linux 内核限制(调整)输入流量比较困难。您可以尝试 IMQ 补丁http://www.linuximq.net/为您的内核。您还需要修补 iptables。然后您可以“标记”数据包以将其发送到 IMQ 设备,tc然后imq0您可以根据需要调整流量的设备。

2)另一个简单但不准确的解决方案是使用 iptables,但它基于数据包计数(您需要估算协议/连接的平均数据包大小)

iptables -A INPUT -p tcp --dport 8128:8191 -m limit --limit 5/seconds -j ACCEPT
iptables -A INPUT -p tcp --dport 8128:8191 -j DROP

您需要这两行,第一行每秒接受所有 IP 的前 5 个数据包,第二行丢弃所有数据包。

相关内容