多端口模块是否iptables
提供优于多个单独规则的性能优势?换句话说,是这样的:
iptables -A INPUT -p tcp -m multiport --sports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,80 -j ACCEPT
..比这更有效:
iptables -A INPUT -p tcp --sport 1 -j ACCEPT
iptables -A INPUT -p tcp --sport 2 -j ACCEPT
iptables -A INPUT -p tcp --sport 3 -j ACCEPT
iptables -A INPUT -p tcp --sport 4 -j ACCEPT
iptables -A INPUT -p tcp --sport 5 -j ACCEPT
iptables -A INPUT -p tcp --sport 6 -j ACCEPT
iptables -A INPUT -p tcp --sport 7 -j ACCEPT
iptables -A INPUT -p tcp --sport 8 -j ACCEPT
iptables -A INPUT -p tcp --sport 9 -j ACCEPT
iptables -A INPUT -p tcp --sport 10 -j ACCEPT
iptables -A INPUT -p tcp --sport 11 -j ACCEPT
iptables -A INPUT -p tcp --sport 12 -j ACCEPT
iptables -A INPUT -p tcp --sport 13 -j ACCEPT
iptables -A INPUT -p tcp --sport 14 -j ACCEPT
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
在第一种情况下,每个包都检查tcp
和multiport
模块,但只有一个规则。在第二种情况下,为每个包检查 15 条规则,但对于每个规则,只tcp
处理模块。
我做了以下简单的网络拓扑:
server1[eth2] <--> [enp0s31f6]server2
eth2
inserver1
和enp0s31f6
in都是server2
1GigE 网络适配器,它们使用 5m Cat5e 电缆连接。server1
当我从没有任何防火墙规则的情况下下载 10000 MiB 文件时server2
,吞吐量为 942Mbps。然后我生成了 4369 条这样的规则:
for i in {1..65535}; do if ((i%15 == 0)); then iptables -A INPUT -p tcp -m multiport --sports $p$i -j ACCEPT; p=; else p=$p$i,; fi; done
这意味着有 4369multiport
条规则,每条规则中有 15 个端口。例如:
# iptables -L INPUT 1 -v -n --line-numbers
1 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport sports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
# iptables -L INPUT 4369 -v -n --line-numbers
4369 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport sports 65521,65522,65523,65524,65525,65526,65527,65528,65529,65530,65531,65532,65533,65534,65535
#
现在当我执行wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
时server2
,令我惊讶的是,吞吐量仍然是 942Mbps。下一步,我刷新了INPUT
链并生成了 65535 条规则,如下所示:
for i in {1..65535}; do iptables -A INPUT -p tcp --sport $i -j ACCEPT; done
我再次执行wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
,server2
现在吞吐量下降到 580Mbps。那么我是否正确,在极端情况下,该multiport
方法更有效?但是,在没有几万条规则或几十Gbps流量的正常情况下,有没有实际的区别?
iptables 遍历表中的每个规则,直到找到与终止目标的匹配项,因此更少的规则意味着更少的 CPU 使用率。尽管有些规则比其他规则运行得更快,例如15 个端口的多端口规则可能比等效的设置规则更快(如 Hauke Laging 的回答)。因此,不仅规则的数量很重要,它们的类型也很重要。
tcp/udp、multiport和set match 扩展的源代码提供了一些经验法则,但是因为很难预测哪里慢,我建议对可能的 iptables 规则集进行基准测试,看看哪个更快。例如,我使用仅包含 3 个端口的列表运行iperf3,并且tcp模块比提供相似吞吐量的多端口和设置模块快一点。
如果你还在使用微基准测试,我使用这个非常非常基本的SystemTap脚本计算了运行
ipt_do_table
内核函数所需的 CPU 周期:这些是我在运行 Linux 4.15 的虚拟机上遍历所有规则的数据包的结果:
我不知道,Linux 如何在操作码级别处理 Netfilter 规则。但是多端口方法可以通过单个操作进行多次检查。
由于 1Gb/s 对于 CPU(即使是慢速 CPU)来说并不多,因此您需要极端情况也就不足为奇了。但是这两种方法甚至可能在相同的吞吐量下产生完全不同的负载。由于这是内核的东西,它可能甚至没有显示在
/proc/loadavg
. 因此,您必须在同一系统上运行 CPU 密集型应用程序并测量其性能才能看到真正的差异。但我认为你的比较有点不公平,因为多端口检查一次,
-p tcp
而多规则检查 65536 次。因此你会这样:我只是意识到你不能忽略 TCP 检查,因为它是
--dport
. 但这是多规则方法较慢的原因之一。我不确定多端口是否适用于像您这样的情况。为创建巨大的比较列表
ipset
。所以这可能是你真正想要的。