
iptables DNAT/SNAT 設定に関する質問はここにたくさんありますが、現在の問題を解決できるものは見つかりませんでした。eth0
の IP アドレス (例: 192.168.0.20) にバインドされたサービスがあり、別のサーバーと共有されている eth0:0 (192.168.0.40) の IP アドレスもあります。アクティブなサーバーは 1 つだけなので、このエイリアス インターフェイスはアクティブなサーバーに応じて切り替わります。サービスによってトラフィックが受け入れられるように、DNAT ルールを使用して宛先 IP を変更します。
iptables -t nat -A PREROUTING -d 192.168.0.40 -p udp --dport 7100 -j DNAT --to-destination 192.168.0.20
また、このサービスからのすべての送信トラフィックが共有 IP から送信されたように見えるようにして、アクティブ/スタンバイ フェイルオーバーが発生した場合に応答が返されるようにしたいと考えています。
iptables -t nat -A POSTROUTING -p udp --sport 7100 -j SNAT --to-source 192.168.0.40
問題は、SNAT ルールが常に実行されるわけではないことです。着信トラフィックにより、次のような接続追跡エントリが発生します。
[root]# conntrack -L -p udp
udp 17 170 src=192.168.0.185 dst=192.168.0.40 sport=7100 dport=7100 src=192.168.0.20 dst=192.168.0.185 sport=7100 dport=7100 [ASSURED] mark=0 secmark=0 use=2
つまり、POSTROUTING チェーンは実行されず、送信トラフィックは実際の IP アドレスを送信元として送信されます。
このポート番号の conntracking を防ぐために、raw テーブルに NOTRACK ルールを設定できると考えていますが、これを機能させるより優れた、またはより効率的な方法はありますか?
編集 - 別の質問: 共有 IP アドレスがサーバー間で交換されたときにネットワークに接続したり切断したりできるように、バインドできるが使用できないインターフェイスを (CentOS/Linux で) 持つ方法はありますか?
答え1
問題の解決策を見つけました。
カーネルパラメータを使用することでnet.ipv4.ip_nonlocal_bind=1
、まだ存在しないアドレスにサービスをバインドすることができます。eth0
:0 インターフェイスが起動すると、トラフィックはサービスによって受け入れられます。ARP などは ucarp/networking によって処理されます。これを実行すると、DNAT/SNAT ルールはまったく必要ありません。
答え2
2 つの選択肢を提案できます。そのうちの 1 つを選択するか、独自の選択肢を選択してください。
ワイルドカード アドレスをリッスンするようにサービスを設定すると、DNAT ルールを完全に回避できます。すると、送信パケットに SNAT ルールが適用されます。
または、使用している HA ソリューションに応じて、移行時にフローティング IP (192.168.0.40) でリッスンするサービスを開始するように構成することもできます。
あまり関係ない話だが、この種の迷惑行為はOpenBSD CARPCARP を使用すると、すべてのノードに仮想 IP が設定されますが、アクティブになるのは 1 つのノードだけです。つまり、すべてのノードで仮想 IP をリッスンできるということです。
これはあまりきれいではありませんが、すべてのノードで仮想 IP を設定し (さらに起動し)、arptables
その IP の ARP 応答またはアナウンスを無効にすることができます。その後、ノードがマスターまたはスレーブになったときに、ucarp を使用して ARP ルールを有効または無効にすることができます。