web-dev-qa-db-ja.com

IPTablesは、ESTABLISHEDを含むすべてのUDPパケットをリダイレクトします

現在、IPtablesには次のようなルールが設定されています。

-A PREROUTING -d dstip/32 -p udp -m udp --dport 27035 -m u32 --u32 "0x0>>0x16&0x3c@0x8=0xffffffff&&0x0>>0x16&0x3c@0xc=0x54536f75&&0x0>>0x16&0x3c@0x10=0x72636520&&0x0>>0x16&0x3c@0x14=0x456e6769&&0x0>>0x16&0x3c@0x18=0x6e652051&&0x0>>0x16&0x3c@0x1c=0x75657279" -j REDIRECT --to-ports 21010

これにより、そのペイロードを含むパケットがキャッシュプログラムにリダイレクトされます。これはうまく機能します。ただし、「新しい」パケットのみがこのNATルールに当てはまります。いくつか調べた後、次のように設定することでこの問題を解決できました。

Sudo sysctl -w net.netfilter.nf_conntrack_udp_timeout=0
Sudo sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=0

これにより、すべてのUDPパケットがこれに設定されていたという別の問題が発生しました。小さなUDPフラッド中に、これによりサーバー上のすべてのudpトラフィックが停止します。

特定のペイロードを含むすべてのUDPパケットを同じマシンの別のポートにリダイレクトする必要があります。このペイロードに応答する別のプログラムがこのポートでリッスンしています。これは、通常、アプリケーションの1つがフリーズするクエリフラッドが原因であるため、このクエリを別のプログラムにオフロードします。

これに対する解決策はありますか?何の答えもなく何ヶ月も探し回っています。

4
user1372896

この問題を解決するには、まったく異なる2つの方法があります。

conntrackzones のiptables

Contrackゾーンでは、(ネットワーク名前空間ごとに)複数のconntrackインスタンスを使用できます。

orig-zoneタグを追加 パケットに追加してフローを作成することにより、2つのconntrackインスタンスで、(半分作成された)フローを2つの部分に分割できます。通常のパケットと一致するパケットです。自分の流れ。したがって、通常のNATルールは引き続き機能し、1回ではなく2回発生する可能性があります。1回は通常のパケット用、もう1回は一致するパケット用です。

テストを複製する代わりに、パケットに対して1つのテストが実行された後にマークが付けられます。

iptables -t raw -A PREROUTING -d dstip/32 -p udp -m udp --dport 27035 -m u32 --u32 "0x0>>0x16&0x3c@0x8=0xffffffff&&0x0>>0x16&0x3c@0xc=0x54536f75&&0x0>>0x16&0x3c@0x10=0x72636520&&0x0>>0x16&0x3c@0x14=0x456e6769&&0x0>>0x16&0x3c@0x18=0x6e652051&&0x0>>0x16&0x3c@0x1c=0x75657279" -j MARK --set-mark 1
iptables -t raw -A PREROUTING -m mark --mark 1 -j CT --zone-orig 1
iptables -t nat -A PREROUTING -p udp -m mark --mark 1 -j REDIRECT --to-ports 21010

Conntrackの結果の例:

# conntrack -E -p udp --orig-port-dst 27035
    [NEW] udp      17 30 src=10.0.3.1 dst=10.0.3.66 sport=52670 dport=27035 [UNREPLIED] src=10.0.3.66 dst=10.0.3.1 sport=27035 dport=52670
    [NEW] udp      17 30 src=10.0.3.1 dst=10.0.3.66 sport=52670 dport=27035 zone-orig=1 [UNREPLIED] src=10.0.3.66 dst=10.0.3.1 sport=21010 dport=52670
 [UPDATE] udp      17 30 src=10.0.3.1 dst=10.0.3.66 sport=52670 dport=27035 src=10.0.3.66 dst=10.0.3.1 sport=27035 dport=52670
 [UPDATE] udp      17 30 src=10.0.3.1 dst=10.0.3.66 sport=52670 dport=27035 zone-orig=1 src=10.0.3.66 dst=10.0.3.1 sport=21010 dport=52670

notrack および パケットヘッダーフィールドマングリング のnftables

カーネル> = 4.10が必要

(もちろん、zonesメソッドはnftablesで実装できます)。

ここでNATは、リダイレクトされたポートからの着信パケットとすべての発信応答パケットを照合するために、conntrackを無効にしてステートレスで実行されます。

nft add table ip raw
nft add chain ip raw prerouting '{type filter hook prerouting priority -300;}'
nft add chain ip raw output '{type filter hook output priority -300;}'
nft add rule ip raw prerouting ip daddr dstip/32 udp dport 27035 @th,64,32 == 0xffffffff @th,96,32 == 0x54536f75 @th,128,32 == 0x72636520 @th,160,32 == 0x456e6769 @th,192,32 == 0x6e652051 @th,224,32 == 0x75657279 notrack udp dport set 21010
nft add rule ip raw output udp sport 21010 notrack udp sport set 27035

u32と同等の生のペイロードフィルターは単純化でき、実際にはnftablesによって自動的に単純化されることに注意してください。u128で見られるように、nftablesは内部でnft --debug=netlink list ruleset -aを処理するようです)。

1
A.B