一見明らかiptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77
と思われるものが機能しない理由は、リターンパケットのルーティング方法です。
192.168.12.87に送信されるパケットを192.168.12.77に単純にNAT変換するルールを設定できますが、192.168.12.77はクライアントに直接返信を送信します。これらの応答は、iptablesルールがNATを実行しているホストを通過しないため、一方向のパケットは変換されますが、他の方向のパケットは変換されません。
この問題を解決するには、3つのアプローチがあります。
- 最初のホストでは、DNATを実行するだけでなく、SNATも実行して、リターントラフィックが最初のホストを介して送り返されるようにします。ルールは次のようになります
iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
- IP層ではなくイーサネット層でパケットをDSRロードバランシングとDNATからインスピレーションを得てください。パケットの宛先MACを192.168.12.77のMACに置き換え、IPレイヤーに触れることなくイーサネットで送信することにより、192.168.12.77がダミーインターフェイスで192.168.12.87を構成し、TCP接続を終了できるようになります。クライアントが認識しているサーバーIPを使用します。
- 最初のホストで単純な(動作していない)ソリューションを使用します。次に、リターントラフィックでSNATを実行して、2番目のホストでリターンパケットを処理します。ルールは次のようになります
iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87
これらの3つのソリューションにはそれぞれ欠点があるため、この特定の転送を本当に行う必要がある場合は慎重に検討する必要があります。
- SNATを使用するとクライアントIPが失われるため、ホスト番号2はすべての接続が192.168.12.87から来たと見なします。さらに、すべての応答パケットにホスト番号1の帯域幅を使用します。これにより、他のアプローチではより直接的なルートを使用できます。
- DSRアプローチは、2つのノード間の他のすべての通信を中断します。DSRアプローチは、サーバーアドレスがどのホストのプライマリIPでもない場合にのみ適切です。各ホストには、DSR IPではないプライマリIPが必要です。
- あるホストで接続追跡を使用して1つの方向に変換し、別のホストで接続追跡を使用して別の方向に変換するのは見苦しいため、さまざまな方法で解決できます。たとえば、いずれかのホストでNATによってポート番号が変更された場合、それらを再構成する方法はありません。また、最初のパケットがACKではなくSYN-ACKである場合、接続追跡が正常に機能することも指定されていません。
3つのアプローチのうち、最初のアプローチが最も効果的だと思います。したがって、クライアントIPアドレスを知る必要がない場合は、それが推奨されます。
また、NATを完全に忘れて、MACまたはIP層の問題を解決しようとしないこともできます。HTTPレイヤーまでずっと進んで、そこで解決策を探すことができます。その場合、解決策はHTTPプロキシです。192.168.12.87にHTTPプロキシをインストールし、適切に構成する場合、リクエストを192.168.12.77に転送し、応答を返送することができます。さらに、元のクライアントIPを保持するX-Forwarded-Forヘッダーを挿入できます。192.168.12.77上のサーバーは、192.168.12.87からのX-Forwarded-Forヘッダーを信頼するように構成する必要があります。