質問は簡単ですが、具体的な回答がなく、関連するトピックを無数に調べたので、答えは違うかもしれません。
ポート1234
をx.x.x.x
からy.y.y.y
に転送したい(インターネット上のさまざまな場所、つまりy.y.y.y
は10.a.b.c
などの内部IPではない) y.y.y.y
がx.x.x.x
に接続している元のソースIPを取得できる方法。
現在、通常のSNATまたはMASQUERADEルールを使用してx.x.x.x
をソースIPとして認識しています。 y.y.y.y
が内部IP(x.x.x.x
で実行されているlxcコンテナーなど)の場合、同じルールが機能し、コンテナーは実際のソースIPを認識できますが、y.y.y.y
が外部の場合は認識できません。
これは何らかの方法で達成できますか?
NAT –いいえ。IPパケットには「ソース」フィールドが1つだけあります。
Iptablesに元のクライアントアドレス(DNATのみ)を保持させると、yyyyはその元のクライアント(通信していると思う)に直接応答を送信しようとしますxxxxであり、yyyyからのパケットを予期していません)。
Iptablesに自分のアドレスを新しいソース(DNAT + SNAT)として配置させると、y.y.y.yは元のソースアドレスを認識しなくなります。
(これは実際にはLANから同じLANにポート転送しようとする場合と同じ問題であり、2番目の方法は「NATヘアピニング」または「NATリフレクション」と呼ばれます。)
これを機能させるには、xxxxとyyyyの間にトンネル/ VPNが必要です。受信した元のパケットを変更せずに別のIPパケット内にラップします。はyyyyに送信されます(これにより、トンネリングされたパケットがアンラップされ、元のソースが表示されます)。
もちろん、これは、トンネルを構成するためにルート権限が必要であることを意味します両方のシステムで。さらに、宛先(y.y.y.y)は「ポリシールーティング」をサポートする必要があります–LinuxおよびFreeBSDpfはこれに対応しています。すべてをVPN経由でルーティングするルールが必要ですif送信元アドレスがVPNアドレスです。
Iptables DNATルールは引き続き必要ですが、その「宛先」はyのVPNアドレスであり、パブリックアドレスではありません。これには、基本的な「IP-in-IP」からGRE、OpenVPN、WireGuardまで、任意のトンネル/ VPNタイプを使用できます。例えば:
x.x.x.x
トンネルを立ち上げる:
ip link add gre-y type gre local x.x.x.x remote y.y.y.y ttl 64
ip link set gre-y up
ip addr add 192.168.47.1/24 dev gre-y
LANの場合と同様に、ポート転送ルールを追加します。
iptables -t nat -I PREROUTING -p tcp --dport 1234 -j DNAT --to-destination 192.168.47.2
y.y.y.y
トンネルを立ち上げる:
ip link add gre-x type gre local y.y.y.y remote x.x.x.x ttl 64
ip link set gre-x up
ip addr add 192.168.47.2/24 dev gre-x
それが機能することを確認してください:
ping 192.168.47.1
ポリシールーティングを設定して、応答(および応答のみ)がトンネルを通過するようにします。
ip route add default via 192.168.47.1 dev gre-x table 1111
ip rule add pref 1000 from 192.168.47.2 lookup 1111
(別のトンネル/ VPNタイプを使用するには、「トンネルの起動」部分のみを置き換えます。)
いいえ、それを達成することはできません。問題は、ルーティングが機能しないことです。
ホストE
(外部)はパケットをホストF
(フォワーダー)に送信します。 F
は、同じ送信元のパケットをホストD
(宛先)に送信します。この部分は、D
が内部か外部かに関係なく機能します。
ここで、D
は回答を返す必要があり、それをパケット内の送信元アドレスE
に送信します。
D
が内部ホストであり、F
がD
のデフォルトゲートウェイである場合、パケットはF
を通過します。ここで、ソースはD
応答パケットのF
に変更されます。ホストE
はF
からのパケットを確認し、すべてが正常です。D
が外部ホストの場合、F
はD
のデフォルトゲートウェイではないため、D
は回答をE
。ホストE
はD
から回答を取得しますが、F
からの回答を期待しているため、D
からのパケットを破棄します。ホストE
は数回再試行し、間違った送信元アドレスからの回答を再度破棄し、最終的にタイムアウトします。送信元アドレスがリターンパケットに使用されるため、おそらくこれを達成することはできません。したがって、送信元アドレスがNATの背後にある場合、より広いインターネットから到達することはできません。
一般的に使用されている回避策は少なくとも2つあります(追加のソフトウェアと構成が必要です)。1つは、VPNを使用してルーターをバイパスするか、ルーターと宛先の間で使用して、宛先が送信元に到達する方法を認識できるようにすることです。
HTTPおよびHTTPSの場合、IPTABLESファイアウォールルールを使用せず、代わりにルーターで(透過的または通常の)プロキシを使用し、プロキシサーバーに外部アプリケーションがアクセスして処理できるX-FORWARDED-FORヘッダーを追加させます。 。
正確なアプリケーションとファイアウォールによっては、リクエストの送信元の送信元ポートを変更することで、「相対的な」内部IPアドレスをマークすることもできる場合があります(ルーターのアドレスから送信されますが、取得できる場合があります。ルーターの背後にあるどのシステムが送信元ポートに基づいて送信したかのヒント)。私はこれが実際に使われるのを見たことがありません。