iptablesとPREROUTINGを使用してUDPパケットを2つの異なる宛先に設定する

iptablesとPREROUTINGを使用してUDPパケットを2つの異なる宛先に設定する

iptablesを使用して、パケットを介してUDPを2つの異なる外部/リモートIPに送信しようとしています。

現在、次のコマンドを実行しています。

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 3070 -j DNAT --to-destination 192.111.111.111:5640
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 3070 -j DNAT --to-destination 167.111.111.111:5640

ただし、UDPパケットはiptablesの規則を調べてから移動するため、機能しません192.111.111.111:5640。別のルールを最初に入れると、UDPパケットは2番目の宛先に移動します。実際の宛先を組み合わせるために範囲機能を試しましたが、範囲が内部IPではないため、パケットはどこにもありません。

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 3070 -j DNAT --to-destination 192.111.111.111-167.111.111.111:5640-5640

### note: I also tried
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 3070 -j DNAT --to-destination 192.111.111.111-167.111.111.111:5640-5641

where the port is increased by one on the secondary server

両方のコマンドが個別に機能し、両方のコマンドが同じルール階層にある場合は、1つのコマンドのみが機能することを確認できます。

TEEまた、IPの1つを別のゲートウェイとして使用してみましたが、それも機能しません。 iptablesでこれを行う方法はありますか?それとも、マルチターゲット汎用UDPフォワーダを作成したときにマークを見逃しましたか?

UDPパケットは同時に配布され、各対応するサーバーに複製する必要があります。現在のユースケースは、サーバーAとサーバーBの両方のプロセスにUDPパケットが必要ですが、パケット転送元では1つのサーバーしか指すことができないことです。つまり、udpパケットを送信するサーバC->サーバD->サーバBとサーバAにパケットをコピーして送信します。

助けやアドバイスをありがとうございます。

答え1

シンプルなユーザーエリアツール

まず、UDPパケットを受信し、A用とB用にそれぞれ1つずつ2つのコピーを送信するサーバーD上で実行される特別なツールを使用することをお勧めします。これは次の方法で行うことができます。Bashプロセスの交換+ティー+ソカット(緩く適用された例udp-multi-socat.sh便利な逆順で以下があります。ティーすぐに実行)、場合によってはバッファリングが発生しない可能性があるかどうかわかりません(専用アプリケーションを作成する方が良い)。

socat -U - udp4-recv:3070 | tee >(socat -u - udp4-datagram:167.111.111.111:5640) | socat -u - udp4-datagram:192.111.111.111:5640

カーネルの使用(iptables ... -j TEE)

つまり、「カーネルヘルパー」メソッドの場合はiptablesがあります。ティーパケットの宛先をコピーできます。レプリケーションは通常のルーティング処理をバイパスする必要があるため、レプリケートされたパケットは直接アクセスできる他のホスト(--ゲートウェイ範囲)。これがなければ、複製されたパケットを処理する良い方法はないようです。ティー

公平に言えば、ネットワークネームスペースを使用してこのホストを作成できます。その後、冗長トラフィックは、ルーティングスタックとiptablesを介してホストDに再注入されます。これで、このトラフィックは別のインターフェイスから来るため、さまざまな方法でDNATedできます。非対称ルーティングとプロセスの冗長性により、いくつかの調整が必要です(緩み)。rp_フィルタ仮想インターフェイスからさまざまなconntrack(開始)領域トラフィックを差別化するためにつながるIPだけを知り、インターフェイスは不明です)

以下はサーバーDで使用される構成です(一部の重複を防ぐことはできますが、読みにくい)。

ip netns del dup 2>/dev/null || : # to remove previous instance, if needed
ip netns add dup

ip link add name dup1 type veth peer netns dup name eth0
ip link set dup1 up
ip -n dup link set eth0 up
ip address add 10.10.10.1/24 dev dup1
ip -n dup address add 10.10.10.2/24 dev eth0
ip -n dup route add default via 10.10.10.1
sysctl -q -w net.ipv4.conf.dup1.rp_filter=2
ip netns exec dup sysctl -q -w net.ipv4.conf.eth0.forwarding=1
iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 3070 -j TEE --gateway 10.10.10.2
iptables -t raw -A PREROUTING -i dup1 -p udp --dport 3070 -j CT --zone-orig 1
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 3070 -j DNAT --to-destination 192.111.111.111:5640
iptables -t nat -A PREROUTING -i dup1 -p udp --dport 3070 -j DNAT --to-destination 167.111.111.111:5640

このアプローチを使用すると、AとBの両方の応答もCに戻すことができます(Cは両方とも同じ初期ターゲットから来たと思います)。したがって、Aを聞いているものがない場合または雨、一つICMP 宛先ポートに接続できません。中断することを選択できるソースCに送信されます。これを防ぐには、どこかにファイアウォールを追加する必要があります。

関連情報