元のIPアドレスを維持しながらパケットを転送する方法

元のIPアドレスを維持しながらパケットを転送する方法

クライアントの元のIPアドレスを維持しながら、あるサーバーから別のサーバーに(「プロキシとして」)パケットを転送する必要があります。トポロジは次のとおりです。 XXXX - パブリックIP1(「プロキシサーバー」)YYYY - パブリックIP2(仮想化ホスト)172.16.0.2 - プライベートIP(Webサーバーを持つ仮想マシン)

some public IP ---> X.X.X.X ---> Y.Y.Y.Y ---> 172.16.0.2 (web server)

XXXXとYYYY転送が有効になっているシステムで。

XXXX 経由の特定のパブリック IP のトラフィックは XXXX の YYYY にルーティングされますが、そこには到達しません。 tcpdumpを使ってキャプチャしました。 「プロキシサーバー」で偽装を使用すると正常に動作しますが、元のIPアドレスは保持されません。 YYYYから172.16.0.2までのみポート80にDNATを使用し、iptables -t nat -A PREROUTING -d Y.Y.Y.Y/32 -i venet0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.16.0.2:80YYYY:80を試すと正常に動作します。問題は、パブリックIP XXXXを使用する「プロキシサーバー」で発生する可能性が高いです。

「プロキシサーバー」ホストIP XXXX

インターネットに接続するためのインターフェイスは1つだけeth0です。

iptablesルール:(フィルタテーブルからの転送を許可)

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination Y.Y.Y.Y:443

ルーティングテーブル:基本テーブルを使用します。

default via X.X.X.1 dev eth0 onlink

ホストIP YYYY

インターネットに接続するためのインターフェイスはvenet0 1つだけです。 VM では Qemu とインターフェイス br0 を使用します。

iptablesルール:(フィルタテーブルからの転送を許可)

iptables -t nat -A PREROUTING -d Y.Y.Y.Y/32 -i venet0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.16.0.2:443
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 ! -o br0 -j MASQUERADE

ルーティングテーブル:基本テーブルを使用します。

default via 255.255.255.254 dev venet0

ホストIP 172.16.0.2

インターネットへのインターフェイスはens6ルーティングテーブルが1つだけです。基本テーブルを使用します。

default via 172.16.0.1 dev ens6 proto static

gapsfが答えたiptablesルールによると:

XXXX iptables ルール:

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination Y.Y.Y.Y
iptables -t nat -A POSTROUTING -s Y.Y.Y.Y/32 -o eth0 -p tcp -m tcp --sport 443 -j SNAT --to-source X.X.X.X
iptables -A FORWARD -d Y.Y.Y.Y/32 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s Y.Y.Y.Y/32 -p tcp -m tcp --sport 443 -j ACCEPT

YYYY iptablesルール:

iptables -t nat -A PREROUTING -i venet0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.16.0.2:443
iptables -t nat -A POSTROUTING -s 172.16.0.2/32 -o venet0 -p tcp -m tcp --sport 443 -j SNAT --to-source Y.Y.Y.Y
iptables -A FORWARD -d 172.16.0.2/32 -i venet0 -o br0 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s 172.16.0.2/32 -i br0 -o venet0 -p tcp -m tcp --sport 443 -j ACCEPT

172.16.0.2 iptablesルール:

iptables -A INPUT -i ens6 -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A OUTPUT -o ens6 -p tcp -m tcp --sport 443 -j ACCEPT

助けてもらえますか?問題は何ですか?

答え1

コメントでは、トラフィックを転送しようとしているWebサーバーに、パケットをWebクライアントに直接返すパスがないことを示しました。これは非常に一般的なシナリオですが、iptablesには複雑すぎます。

一般的な解決策は次のとおりです。

  1. Webサーバーへのデフォルトパスを持つコンピューターである「DMZ」サブネットのハードウェアまたはソフトウェアロードバランサー製品。ロードバランサーには、クライアントが知っているパブリックXXXX IPアドレスがあり、DNATを介して同じソースアドレスを使用するWebサーバーにトラフィックを転送します。ロードバランサーはWebサーバーのデフォルトゲートウェイであるため、リターンパケットはロードバランサーを介して再配信され、リターントラフィックに対してSNATを実行できます。このような複雑なソフトウェアおよび/またはハードウェアのコストは、多くの組織で手に負えない場合があります。

  2. Webサーバーにトラフィックを転送するときにSNATを実行しますが、クライアントの物理IPアドレスをWebサーバーソフトウェアに通知するHTTPヘッダーを追加するには、プロキシを使用します。この目的で一般的に使用されるヘッダーはですX-Forwarded-For:。多くのHTTPサーバーライブラリは自動的にこのヘッダーを認識し、ヘッダーのIPアドレスをアプリケーションで使用できるようにします。一部のアプリケーションはヘッダーに単一のIPアドレスのみを期待し、一部はアドレスリストを処理できます(トラフィックがプロキシに到達する前にプロキシを通過できるため)。ほとんどのネットワークプロキシソフトウェアはこのヘッダーを追加できます。

他のすべてと同様に、妥協があります。 HTTPトラフィックをプロキシしてヘッダーを追加する2番目のオプションでは、プロキシソフトウェアが機能するようにHTTPトラフィックが許容可能な規格に準拠する必要があります。クライアントが HTTP ベースが緩いが完全に互換性のないカスタム プロトコルを使用している場合、プロキシが要求を変更しようとすると問題が発生する可能性があります。たとえば、プロトコルが64kバイトより長いURLを使用している場合です。 (数年前の仕事ですが、以前もこの問題が発生しました。)

あなたが言及した要件を考慮すると、#2はあなたに最適なソリューションだと思います。ネットワークトラフィックが増加すると、トラフィックが超過し、より複雑で高価な負荷分散ソリューションが必要になる可能性があります。

答え2

高価なハードウェアは必要ありません。ルーティング+ iptablesだけで十分だと思います。XXXX ホストには 1 つのインターフェイスしかありません。

XXXXから

ip route add default via eth0
PREORUTING in eth0 dport 80 DNAT to Y.Y.Y.Y
POSTROUTING out eth0 src Y.Y.Y.Y sport 80 SNAT to X.X.X.X
FORWARD dst Y.Y.Y.Y dport 80 ACCEPT
FORWARD src Y.Y.Y.Y sport 80 ACCEPT

ゆうYYYY

ip route add default via venet0
ip route add 172.16.0.2 via br0
PREROUTING in venet0 dport 80 DNAT to 172.16.0.2
POSTROUTING out venet0 src 172.16.0.2 sport 80 SNAT to Y.Y.Y.Y
FORWARD in venet0 out br0 dst 172.16.0.2 dport 80 ACCEPT
FORWARD in br0 out venet0 src 172.16.0.2 sport 80 ACCEPT

172.16.0.2から

ip route add default via 172.16.0.1
INPUT in ens6 dport 80 ACCEPT
OUTPUT out ens6 sport 80 ACCEPT

パート2
XXXX iptables ルール:

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination Y.Y.Y.Y
iptables -t nat -A POSTROUTING -s Y.Y.Y.Y/32 -o eth0 -p tcp -m tcp --sport 443 -j SNAT --to-source X.X.X.X
iptables -A FORWARD -d Y.Y.Y.Y/32 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s Y.Y.Y.Y/32 -p tcp -m tcp --sport 443 -j ACCEPT

YYYY iptablesルール:

iptables -t nat -A PREROUTING -i venet0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.16.0.2:443
iptables -t nat -A POSTROUTING -s 172.16.0.2/32 -o venet0 -p tcp -m tcp --sport 443 -j SNAT --to-source Y.Y.Y.Y
iptables -A FORWARD -d 172.16.0.2/32 -i venet0 -o br0 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s 172.16.0.2/32 -i br0 -o venet0 -p tcp -m tcp --sport 443 -j ACCEPT

172.16.0.2 iptablesルール:

iptables -A INPUT -i ens6 -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A OUTPUT -o ens6 -p tcp -m tcp --sport 443 -j ACCEPT

関連情報