多端口模块是否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
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,每个包都会检查tcp
和multiport
模块,但只有一条规则。在第二种情况下,为每个包检查 15 条规则,但对于每个规则,仅tcp
处理模块。
我做了一个简单的网络拓扑如下:
server1[eth2] <--> [enp0s31f6]server2
Run Code Online (Sandbox Code Playgroud)
in和in都是1GigE网络适配器,并通过5m Cat5eeth2
电缆连接。当我在没有任何防火墙规则的情况下从到下载 10000 MiB 文件时,吞吐量为 942Mbps。然后我生成了 4369 个这样的规则:server1
enp0s31f6
server2
server1
server2
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
Run Code Online (Sandbox Code Playgroud)
这意味着有 4369 条multiport
规则,每条规则有 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
#
Run Code Online (Sandbox Code Playgroud)
现在,当我执行wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
inserver2
时,令我惊讶的是,吞吐量仍然是 942Mbps。下一步,我刷新了INPUT
链并生成了 65535 条规则,如下所示:
for i in {1..65535}; do iptables -A INPUT -p tcp --sport $i -j ACCEPT; done
Run Code Online (Sandbox Code Playgroud)
我再次执行wget --report-speed=bits -4 -O /dev/null 10.10.10.1:65535
,server2
现在吞吐量下降到 580Mbps。那么,在极端情况下,这种multiport
方法更有效,我这样说对吗?然而,在没有数万条规则或数十Gbps流量的正常情况下,没有实际区别吗?
iptables 遍历表中的每条规则,直到找到与终止目标的匹配项,因此规则越少意味着 CPU 使用率越低。尽管某些规则比其他规则运行得更快,例如15 个端口的多端口规则可能比等效的设置规则更快(如 Hauke Laging 的答案)。因此,不仅规则的数量很重要,而且规则的类型也很重要。
tcp/udp、多端口和设置匹配扩展的源代码提供了一些经验法则,但由于很难预测哪些地方速度较慢,所以我建议对可能的 iptables 规则集进行基准测试,看看哪一个更快。例如,我运行iperf3,仅包含 3 个端口的列表,并且tcp模块比提供类似吞吐量的多端口和设置模块要快一些。
如果您仍然热衷于微基准测试,我ipt_do_table
使用这个非常非常基本的SystemTap脚本计算了运行内核函数所需的 CPU 周期:
global call_cycles = 0
probe kernel.function("ipt_do_table@net/ipv4/netfilter/ip_tables.c").call {
call_cycles = get_cycles()
}
probe kernel.function("ipt_do_table@net/ipv4/netfilter/ip_tables.c").return {
delta = get_cycles() - call_cycles
printf(" <- delta = %d\n", delta)
}
Run Code Online (Sandbox Code Playgroud)
以下是我在运行 Linux 4.15 的虚拟机上遍历所有规则的数据包的结果:
模块 | 港口 | 规则 | 运行1 | 运行2 | 运行3 | 运行4 | 运行5 |
---|---|---|---|---|---|---|---|
TCP协议 | 4500 | 4500 | 973148 | 1032564 | 856528 | 410894 | 854708 |
多端口 | 4500 | 300 | 89370 | 259250 | 99752 | 225275 | 182256 |
放 | 4500 | 1 | 28463 | 43494 | 28315 | 33589 | 40988 |