iptablesマルチポートモジュールは、複数の個々のルールに比べてパフォーマンス上の利点を提供しますか?

iptablesマルチポートモジュールは、複数の個々のルールに比べてパフォーマンス上の利点を提供しますか?

マルチポートモジュールは、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もチェックしますが、ルールは1つだけです。 2番目のケースでは、パッケージごとに15のルールを調べますが、各ルールごとにtcpモジュールのみを処理します。

次のように単純なネットワークトポロジを作成しました。

server1[eth2] <--> [enp0s31f6]server2

eth2入出力はすべて1GigEネットワークアダプタserver1で、5m Cat5eケーブルで接続されています。ファイアウォールルールなしで10000MiBファイルをダウンロードした場合、スループットは942Mbpsでした。次に、次の4369のルールを作成しました。enp0s31f6server2server1server2

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

multiportこれは、それぞれ15のポートを持つ4,36​​9のルールがあることを意味します。たとえば、

# 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のトラフィックがない一般的な状況では、実質的な違いはありませんか?

答え1

iptables は、終了ターゲットに一致するエントリが見つかるまでテーブル内の各ルールを繰り返すため、ルールが少ないほど CPU 使用率が低くなります。一部のルールは他のルールよりも高速に実行されます。マルチポート15ポートルールは、同等のポートルールよりも速くすることができます。置くルール(例:Hauke Laging回答)。したがって、ルールの数だけでなく、ルールの種類も重要です。

ソースコードはTCP/UDPマルチポートそして置くマッチング拡張はいくつかの経験則を提供しますが、進行速度がどこまで遅くなるかを予測するのは難しい。、可能なiptablesルールセットをベンチマークして、どちらが速いかを確認することをお勧めします。たとえば、私はiperf33つのポートのみを含むリスト伝送制御プロトコルモジュール比マルチポートそして置く同様のスループットを提供するモジュールです。

それでもマイクロベンチマークに興味がある場合は、このプログラムを実行するのに必要なCPUサイクルを計算してみました。ipt_do_table非常に基本的なカーネル関数を使うシステムクリックスクリプト:

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)
}

Linux 4.15を実行している仮想マシンですべてのルールのパケットを繰り返す結果は次のとおりです。

基準寸法 ポート ルール 1 実行 ラン2 実行3 実行4 実行5
伝送制御プロトコル 4500 4500 973148 1032564 856528 410894 854708
マルチポート 4500 300 89370 259250 99752 225275 182256
置く 4500 1 28463 43494 28315 33589 40988

答え2

LinuxがopcodeレベルでNetfilterルールをどのように処理するのかわかりません。ただし、マルチポートアプローチでは、1回の操作で複数のチェックを実行できます。

1Gb/sはCPUにあまり多くないので(遅いCPUでも)極端な場合が必要なのは驚くべきことではありません。ただし、どちらの方法でも、同じスループットでも全く異なる負荷を生成できます。これはカーネルなので、おそらく機能しません/proc/loadavg。したがって、同じシステムでCPU集約型アプリケーションを実行し、パフォーマンスを測定して実際の違いを確認する必要があります。

-p tcpしかし、マルチポートは一度チェックしますが、マルチルールは同じチェックを65536回実行するため、比較が少し不公平だと思います。だからあなたはこれを行います:

iptables -N tcp_ports
iptables -A INPUT -p tcp -j tcp_ports
for ((i=1;i<65536;i++)); do iptables -A tcp_ports --sport $i ...

私はTCPチェックをそのまま無視できないことに気づきました--dport。しかし、これがマルチルールアプローチが遅い理由の1つです。

あなたと同じ状況でマルチポーティングが機能しているかどうかはわかりません。ipset巨大な比較リストが作成されました。だからこれはあなたが本当に欲しいものかもしれません。

ipset create foo bitmap:port range tcp:10000-19999
ipset add foo tcp:10000-19999
iptables -A INPUT -p tcp -m set --match-set foo dst

関連情報