ローカルネットワークから転送されたパブリックIPアドレスへのループバック-ヘアピンNAT


45

これは、ヘアピンNAT(ループバックNAT)に関する標準的な質問です。

この質問の一般的な形式は次のとおりです。

クライアント、サーバー、NATルーターを備えたネットワークがあります。ルーターにはサーバーへのポート転送があるため、そのサービスの一部は外部から利用できます。外部IPを指すDNSがあります。ローカルネットワーククライアントは接続に失敗しますが、外部は動作します。

  • なぜこれが失敗するのですか?
  • 統一された命名スキーム(ローカルと外部の両方で機能するDNS名)を作成するにはどうすればよいですか?

この質問には、他の複数の質問から回答が統合されています。彼らはもともとFreeBSD、D-Link、Microtik、およびその他の機器を参照していました。しかし、彼らは皆同じ​​問題を解決しようとしています。


1
インターネットからのアクセスをテストすることが目的の場合、とにかくルーターのルートやDNS設定をいじっても意味がありません。内部からは、ルーターの内部が機能していることを確認することになります。外部のどこかにプロキシサーバーを使用することをお勧めします。

回答:


16

探しているものは「ヘアピンNAT」と呼ばれます。外部インターフェイスに割り当てられたIPアドレスに対する内部インターフェイスからの要求は、外部側のインターフェイスから着信したかのようにNAT変換する必要があります。

FreeBSDの知識はまったくありませんが、OpenBSDの「pf」マニュアル(http://www.openbsd.org/faq/pf/rdr.html)を使用して、スプリットホライズンDNSの提案されたソリューションを読んでください。 DMZネットワーク、またはTCPプロキシにより、「pf」はヘアピンNATをサポートしていないと思われます。

私は、スプリットホライズンDNSのルートを見て、内部的にURLでIPアドレスを使用せず、代わりに名前を使用します。


私は同じ問題を解決しようとしてこのスレッドに出くわしました。FreeBSDはそのままではヘアピンをサポートしていませんが、内部->外部->内部トラフィックをリダイレクトおよびNATする方法があります。
クリムゾン白ret

例えば: no nat on $int_if proto tcp from $int_if to $int_netnat on $int_if proto tcp from $int_net to $hairpin_int port $hairpin_ports -> $int_ifrdr on $int_if proto tcp from $int_net to $ext_if port $hairpin_ports -> $hairpin_int
紅-白鷺

48

これはヘアピンNATの標準的な質問に引き上げられたので、おそらく現在受け入れられているものよりも一般的に有効な回答が必要だと思いました(FreeBSDに特に関連しています)。

この質問は、ゲートウェイで宛先NAT(DNAT)を導入することで外部ユーザーが利用できるRFC1918アドレスのIPv4ネットワーク上のサーバーによって提供されるサービスに適用されます。内部ユーザーは、外部アドレスを介してこれらのサービスにアクセスしようとします。パケットはクライアントからゲートウェイデバイスに送信されます。ゲートウェイデバイスは宛先アドレスを書き換え、すぐに内部ネットワークに送り返します。ヘアピンターンとの類推により、パケットがゲートウェイでヘアピンNATという名前を生み出すのは、この急激なターンです。

この問題は、ゲートウェイデバイスが送信元アドレスではなく宛先アドレスを書き換えたときに発生します。サーバーは、内部の宛先アドレス(自身のアドレス)と内部の送信元アドレス(クライアントのアドレス)を持つパケットを受信します。そのようなアドレスに直接返信できることを知っているので、そうします。その応答は直接であるため、ゲートウェイを経由しないため、戻りパケットの送信元アドレスを書き換えることによって、初期パケットに対する着信宛先NATの効果のバランスを取る機会がありません。

したがって、クライアントは外部 IPアドレスにパケットを送信しますが、内部 IPアドレスから応答を取得します。2つのパケットが同じ会話の一部であることがわからないため、会話は発生しません。

解決策は、そのような宛先NATを必要とし、内部ネットワークからゲートウェイに到達するパケットの場合、通常は送信元アドレスをゲートウェイのアドレスに書き換えることにより、着信パケットに対してソースNAT(SNAT)を実行することです。サーバーは、クライアントがゲートウェイ自体であると判断し、直接応答します。これにより、ゲートウェイは、リターンパケットの送信元アドレスと宛先アドレスの両方を書き換えることにより、インバウンドパケットに対するDNATとSNATの両方の効果のバランスを取ることができます。

クライアントは、外部サーバーと通信していると考えています。サーバーは、ゲートウェイデバイスと通信していると見なします。すべての関係者は幸せです。この時点で図が役立つ場合があります。

ここに画像の説明を入力してください

一部のコンシューマゲートウェイデバイスは、2番目のNATステップが必要なパケットを認識するのに十分な明るさ​​であり、ヘアピンNATシナリオではすぐに動作します。他の人はそうではないので、そうすることはできません。サーバーフォールトのトピック外のコンシューマグレードデバイスの議論。

通常、適切なネットワークデバイスは動作するように指示されますが、管理者を再推測するビジネスではないため、そうするように指示する必要があります。LinuxはiptablesDNATを次のように使用します。

iptables -t nat -A PREROUTING  -p tcp --dport 80 -j DNAT --to-destination 192.168.3.11

これにより、HTTPポートの単純なDNATが有効になり、上の内部サーバーに接続され192.168.3.11ます。ただし、ヘアピンNATを有効にするには、次のようなルールも必要です。

iptables -t nat -A POSTROUTING -d 192.168.3.11 -p tcp --dport 80 -j MASQUERADE

このようなルールは、適切に機能するために関連するチェーンの適切な場所に配置する必要があり、filterチェーンの設定によっては、NATされたトラフィックのフローを許可するために追加のルールが必要になる場合があります。このような議論はすべてこの回答の範囲外です。

しかし、他の人が言ったように、適切にヘアピンNATを有効にすることは、問題を処理する最良の方法ではありません。最適なのはスプリットホライズンDNSです。組織は、内部ユーザーと外部ユーザーに対して異なる物理サーバーを使用するか、DNSサーバーを構成して、要求クライアントの場所に応じて、元のルックアップに対して異なる回答を提供します。要求元クライアントのアドレス。


ゲートウェイとサーバー間で交換されるパケットのアドレスについて少し疑問に思っています。サーバーがルーターのパブリックIPアドレスをクライアントIPとして認識した場合、より一貫性はないでしょうか?技術的には両方とも機能しますが、他のサーバーがクライアントを認識する方法と一貫性を保つには、パブリックIPを使用する必要があります。
カスペルド

1
最後のケース、「適切なヘアピンNAT」について言及していると確信しています。重要なのは、ルータに戻るように着信パケットの送信元アドレスを書き換えることです。これにより、DNATとSNATの両方を逆にし、問題を回避できます。ルーターがこれを行うために使用する多数のアドレスのどれがより好みのポイントであり、でこれを行うiptables場合は、選択することで確実に構成できるものです。
MadHatterはモニカをサポートします14

1
私も含め、多くの管理者は、スプリットホライズンDNSを病気よりも悪い治療法と考えています。1つの追加のSNATがまったく病気と呼ばれる場合。スプリットビューDNSは人間を混乱させる一方、ルーターの生活を楽にします。このトピックは、ServerFaultの個別の質問/回答でより適切に処理されます。
クバンチク

私の答えは、ヘアピンNATについてです。標準的な「スプリットホライズンDNS」質問を開くことの長所と短所を見ることができます。長所には、SHDNSの使用と問題に特化した質問が含まれますが、短所は、この質問に関連する他の質問がたくさんあることですそれがそれに融合したので、あなたの質問にもそれが起こるかもしれません。私なら、メタに関する問題を提起し、コンセンサスを求めます。もしそのような質問が書かれたら、私はあなたの答えを読むのを楽しみにしています!
MadHatterは、Monicaを

@MadHatter iptablesコマンドはどこに書くべきですか?クライアントまたはゲートウェイまたはサーバー上で?
ロッキーバルボア

9

ここでの問題は、ルーターが内部クライアントのアドレスをNATしないことです。したがって、TCPハンドシェイクは失敗します。

次のIPを想定しましょう

  • クライアント:192.168.1.3
  • サーバー:192.168.1.2
  • ルーター内部:192.168.1
  • 外部ルーター:123.123.123.1

ここで何が起こっているのですか:

  1. クライアント(192.168.1.3)はTCP-SYNを外部IP、ポート80(123.123.123.1:80)に送信します
  2. ルーターはポート転送ルールを確認し、ソースIP(192.168.1.3)を変更せずにパケットをサーバー(192.168.1.2:80)に転送します
  3. クライアントは外部IPからのSYN-ACKを待ちます
  4. サーバーは同じサブネット上にあるため、クライアントに直接返事を返します。パケットをルーターに送信しないため、NATが逆になります。
  5. クライアントは、123.123.123.1。ではなく192.168.1.2からSYN-ACKを受信します。そしてそれを破棄します。
  6. クライアントは、123.123.123.1からのSYN-ACKを待機してタイムアウトします。

4

IPアドレスをどこでもハードコーディングする代わりに、スプリットホライズンDNSを使用しないのはなぜですか?ext.yourdomainは外側で217.xxxを指し、次に内側で192.xxxを指します。


1
少し時間があれば、Split-Horizo​​n DNSとは何か、それがどのように機能するか、および主要な欠点について詳しく説明してください。これは今では標準的な質問であり、より完全な答えがあればいいと思います。
クリスS

2

元のD-Linkルーター(つまり、Rev。D / Virgin Mediaのファームウェアバージョン1.00VGではない)の場合、この問題を回避するために設定を調整できるはずです。(ただし、他の多くの理由で、以前のポスターのDD-WRTの提案に同意します!)

  1. ルーターのWebインターフェースにログインします
  2. 上部の[詳細設定]タブをクリックします
  3. 左側の[ファイアウォール設定]タブをクリックします
  4. クリックしてエンドポイントの独立の下のラジオボタンをTCPエンドポイントのフィルタリング次のスクリーンショットに示すように、(または参照ルータのエミュレータを D-Linkのウェブサイト)
  5. 変更内容を保存; 終わった

D-LinkルーターのWeb UIスクリーンショット

このスクリーンショットはRev. Cモデルのものです。あなたのものはわずかに異なる場合があります。


2

最近、同様の質問に回答しました。Cisco静的NATはLAN側で機能せず、これが正規の質問であることに気付きました。そこで、ここで解決策を要約させてください。

まず、NATを忘れる(可能な場合)-NATの構成に関する質問ではありません。これは、インターネットとLANの両方からNATの背後に配置されたサーバーにアクセスすることです。2つのDNSゾーンを使用することは実行可能な代替手段ですが、常にソリューションとは限りません。しかし、解決策は存在し、信じられないほど単純です(おそらく完璧ではありませんが)。

(1)サーバー上:255.255.255.255マスクを使用して、パブリックIPアドレスをサーバーのネットワークインターフェイスのセカンダリIPアドレスとして追加します(Webサービスまたはサーバー上の任意のものもこのIPアドレスでリッスンする必要があります)。最新のすべてのオペレーティングシステムでこれを行うことができます(または、セカンダリIPをプライマリインターフェイスに追加する代わりに、パブリックIPアドレスが割り当てられたループバックインターフェイスを使用できます)。

(2)LANホスト:パブリックIPアドレスのホストルートを追加します。たとえば、Windowsホストでは次のコマンドを使用します。route -p add 203.0.113.130 mask 255.255.255.255 192.168.1.11(DHCPも使用できます)ルートを配布するための静的ルート」オプション)。または、クライアントとインターネットに面するルーターの間に(a)L3スイッチ/ルーターがある場合は、この(これらの)中間スイッチ/ルーターではなくそのホストルートを構成します。クライアントで。

TCP 3ウェイハンドシェイクに関するもの:提案された構成で問題なく動作します。

フィードバックを提供してください(少なくとも、投票してください)。


要件#2が...これはBYODネットワーク上でうまく動作しない可能
マイケル・

1

同様の問題を抱えている人の視野を広げるために、私の質問に答えます。

ISPに連絡し、問題の解決を試みるよう依頼しました。彼らが提供してくれたのは、サーバー専用の別のパブリックIPアドレスです。今では、FreeBSDのWAN側にローカルトラフィックがあり、ローカルトラフィックからサーバーのパブリックIPへの高速スループットのための特定のパイプを作成しました。


2
このソリューションは、境界ネットワークまたはDMZを実装し、ヘアピンNATとスプリットホライズンDNSの両方に適した代替手段です。
クリスS

1

技術的な観点からこの問題の最良の解決策は、ネットワークでIPv6を有効にすることです。IPv6が有効になっている場合、ドメインのAAAAレコードを作成する必要があります。ルータの外部IPv4を指す既存のAレコードを保持しますサーバーの IPv6アドレスを指すAAAAレコードを作成します

IPv6にはNATを回避するのに十分なアドレスがあるため、IPv6にヘアピンNATは必要ありません。また、IPv6を有効にしてAAAAレコードを作成すると、RFC 8305をサポートするクライアントはIPv4の前にIPv6を試行します。つまり、クライアントはIPv4を使用しないため、IPv4のヘアピンNATも必要ありません。

世界のほとんどでIPv6も有効になるまで、発信接続には既存のIPv4 NATが必要であり、着信接続にはポート転送が必要です。

それも高速です。

IPv6を使用すると、ヘアピンNATよりも優れたパフォーマンスが得られます。

ヘアピンNATを使用すると、クライアントはスイッチを介してルーターにパケットを送信し、ルーターは2ラウンドの変換を実行し、最後にスイッチを介してサーバーにパケットを送信します。サーバーからクライアントへのパケットは、そのパス全体を逆に通過します。

IPv6を使用すると、NATを回避できます。代わりに、パケットはクライアントとサーバー間のスイッチを介して直接送信されます。これは、ラウンドトリップで、スイッチを通過するパスの数を4から2に減らし、ルーターを2回トリップし、ルーターが実行する4つの変換を回避することを意味します。これにより、パフォーマンスが向上します。

これは、ルーターと同じボックスに組み込まれたスイッチを使用する場合でも当てはまります。

ISPにIPv6がない場合はどうなりますか?

IPv6をサポートしていないISPを使用している場合、そのネットワークでサーバーをホストする必要があるかどうか疑問に思います。これらは、ISPが現在IPv6をサポートしていない場合の対処方法に関する私の提案です。

まず、IPv6 が必要であることをISPに伝えます。また、IPv6プロトコルは20年前から存在しているため、IPv6プロトコルをサポートするのに長い間遅れていることを思い出させてください。ISPが他のISPを真剣に探し始めるのに十分でない場合。

IPv6をサポートするISPを見つけた場合、移行期間中は両方のISPで実行できます。新しいISPに接続されたルーターでは、LAN側でIPv4を無効にしてから、両方のルーターのLAN側を同じスイッチに接続できます。IPv4とIPv6は2つの独立したプロトコルであるため、これらの接続が異なるルーターを経由する場合はまったく問題ありません。副次的な利点として、接続の1つに障害が発生した場合、ある程度の冗長性が得られます。

IPv6をサポートするISPが見つからない場合は、サーバーをホスティング施設に移動することを検討する必要があります。ホスティング施設のサーバーを使用すると、地理的な場所への依存度が低くなります。そのため、プロバイダー間で競争が激化するため、ニーズを満たすものを確保できます。

サーバーをホスティング施設に移動しても、クライアントにIPv6が提供されるわけではありませんが、サーバーを移動すると、ヘアピンNATが不要になります。

してはいけないこと

IPv6トラフィックをルーティングする方法がない場合は、IPv6をオンにしてAAAAレコードを作成しないでください。ISPがIPv6をサポートしていないが、とにかくLANでIPv6を有効にし(おそらくRFC 4193アドレスを使用)、AAAAレコードを作成することを選択すると、LAN上のクライアントがLAN上のサーバーに到達するために機能します。しかし、LANと外部の世界との間の通信は最初にIPv6を試行し(これは機能しません)、IPv4へのフォールバックに依存することになりますが、これはせいぜい少し遅いか、最悪でも起こりません。


0

私もこの質問をして(外部IPを使用してファイアウォールの内側からNATされたネットワークサービスにアクセスするにどうすればいいですか?を参照してください)、ここでリダイレクトされましたが、ここの答えは解決策を提供しませんでした(一般的な説明とは対照的に)iptablesここに私のLinux(特定の)ソリューションを提供して、すべての人が数時間の実験を省くようにします。このファイルはiptables-restore形式であり、iptablesに直接読み込むことができます(もちろんIPアドレスを編集した後)。これはWebサーバー(ポート80)用であり、IPv4専用です-IPv6とSSL(ポート443)のルールは類似しています。


# Port forwarding for VM / Container access with „hairpin NAT“.
*nat
:PREROUTING ACCEPT [3:205]
:INPUT ACCEPT [59:670]
:OUTPUT ACCEPT [16:172]
:POSTROUTING ACCEPT [20:257]

# This was simple port forwarding - access works from outside but not from inside
#-A PREROUTING  -4 -p tcp -i eth0 --dport 80 -j DNAT --to web.local:80

# This is real hairpin NAT which allows „web.local“ to access itself via the VM hosts external IP.
# First we need to masquerade any traffic going out the external interface:
-A POSTROUTING -o eth0 -j MASQUERADE

# Then we need to reroute incoming traffic on the public IP to the local IP:
-A PREROUTING  -4 -p tcp -d web.public.com --dport  80 -j DNAT --to web.local:80

# And finally we need to tell the router that the source IP of any traffic
# coming from the LAN must be source-rewritten when going to the web server:
-A POSTROUTING -4 -p tcp -s lan.local/24 -d web.local --dport  80 -j SNAT --to-source web.public.com:80

COMMIT

置き換えlan.localweb.localおよびweb.public.comローカルネットワークを持つ(例えば。10.0.x.0 / 24)、ウェブサーバのローカルIP(例えば10.0.1.2)、およびルーターのパブリックIP(例えば4.5.6.7)。これ-4は、同じファイルでIPv6とIPv4のルールを許可することです(このような行はによって無視されますip6tables)。また、ポート宣言が含まれる場合は、[ブラケット]にIPv6アドレスを入れることを忘れないでください[fe0a:bd52::2]:80

これらはすべて、この質問の説明を実際に実行しようとしたときに髪の毛を抜く原因になりました。何も省いたことを願っています。


wanインターフェースのMASQUERADEは一般に便利ですが、「ヘアピンNAT」の質問とは関係ありません。正規の答えは、lanインターフェイスでMASQUERADEを提案し、代わりにSNATを提案します(SNATはMASQUERADEとほぼ同じです)。やや奇妙なソースIP:portオーバーライドを強制します。
クバンチク

0

ここでのコメントは私の特定の問題に対処しなかったので、ここに答えを追加します。これは、厄介なLinuxカーネルのバグにぶつかったためだと思います。セットアップは次のとおりです。

internet <--> modem 1.1.1.1/30 <--> switch <---> LAN 10.1.1.0/24
                                      ^
        +----------------------+      |
        |              /--eth0 o <----/
        |              |       |           
        | 10.1.1.1/24 br0      |           v (antenna)
        |  1.1.1.2/30  |       |           |
        |              \-wlan0 o ----------/
        +----------------------+ 

複雑な外観にもかかわらず、他のコメントで扱われている状況に関連する唯一の変更は、ソフトウェアブリッジbr0の追加です。これは、ゲートウェイボックスがLANのワイヤレスアクセスポイントでもあるためです。

ゲートウェイボックスは、LAN上のマシンに対してNAT業務を実行しています。イーサネットポートが1つしかないため、ヘアピンNATを実行する必要があります。ここでの他のコメントで示されたiptablesルールで動作するはずですが、Linuxカーネル4.9では少なくとも動作しません。4.9未満では、ゲートウェイボックスはインターネットにアクセスできますが、NAT経由でアクセスしようとするLAN上のマシンはアクセスできません。

tcpdumpeth0にヒットする着信パケットへの応答を表示しますが、br0から抜け出しません。このコマンドを実行すると、以下が修正されます。

ebtables -t brouter -A BROUTING -d 01:00:00:00:00:00/01:00:00:00:00:00 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-dst 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-src 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 -j DROP

そのコマンドが実行される前に、着信パケットは、カーネルのデフォルトの動作に従って処理されます。これは、パケットをブリッジに与え、カーネルのルーティングモジュールを渡すことです。このコマンドは、LANからでないパケットを強制的にブリッジをバイパスし、ルーティングに直接移動させます。つまり、ブリッジはそれらをドロップする機会を得ません。ブロードキャストアドレスとマルチキャストアドレスはブリッジする必要があります。そうしないと、DHCPやmDNSなどが機能しません。IPv6を使用している場合は、IPv6のルールも追加する必要があります。

これを使用して問題を解決したいと思うかもしれません:

brctl hairpin br0 eth0 on
brctl hairpin br0 wlan0 on

私は確かにとても誘惑されました-それは私の最初の試みでした。私がやるとすぐに、LAN上のマシンがインターネットにアクセスできるようになったので、しばらく動作します。その後、次のことが起こりました(そして、私は実験を繰り返すことを気にしませんでした):

  1. LANを介したゲートウェイへのping時間は約10秒間隔で2倍になり、ゲートウェイボックスがLANからアクセスできなくなるまで、0.1ミリ秒から0.2ミリ秒、0.4ミリ秒、0.8ミリ秒、2ミリ秒などに増加しました。パケットストームのように匂いがするが、STPはどこでもオンになった。
  2. すべてのワイヤレスアクセスポイントが死んでからまもなく。
  3. ワイヤレスで何が起こっているのかを診断しようとしたときに、すべてのIP電話が再起動しました。
  4. その後まもなく、有線マシンはLANとのすべての接続を失いました。

唯一の方法は、建物内のすべてのマシンを再起動することでした。唯一の例外はハードウェアスイッチで、再起動できませんでした。電源を入れ直す必要がありました。


0

それは標準的な質問だからです。Sonicwallルーターをお持ちの場合にお答えします。

知っておくべき表現はNATループバックポリシーです

このドキュメントでは、SonicWall LAN上のホストが、FQDNへのサーバーのパブリックIPアドレスを使用して、SonicWall LAN上のサーバーにアクセスする方法について説明します。プライマリLANサブネットが10.100.0.0 / 24で、プライマリWAN IPが3.3.2.1であるNSA 4500(SonicOS Enhanced)ネットワークを想像してください。顧客用のWebサイトがあり、そのホスト名がであるとします。部外者がWebサイトにアクセスできるように必要なポリシーとルールをすでに作成しましたが、実際にはプライベートサイドサーバー10.100.0.2で実行されています。ここで、あなたがプライベート側でラップトップを使用し、IPが10.100.0.200である人を想像してください。パブリック名を使用してサーバーに到達したいのは、ラップトップを持ち歩いているときに同じことをするからです。プライベート側に座って、http://www.example.comをリクエストする場合>、ループバックは、サーバーが実際にローカルIPアドレスのすぐ隣にある場合でも、それが機能することを可能にします。

この機能を許可するには、NATリフレクションまたはヘアピンとも呼ばれるNATループバックポリシーを作成する必要があります。

WANインターフェイスのIPアドレスを使用したループバックポリシー

Login to the SonicWall Management GUI.
Navigate to Manage | Rules | NAT Policies submenu.
Click on the Add button.
Create the following NAT Policy.
Original Source: LAN Subnets (or Firewalled Subnets if you want hosts in other zones to be included)
Translated Source: WAN Interface IP
Original Destination: WAN Interface IP
Translated Destination: (LAN server object)
Original Service: Any
Translated Service: Original
Inbound Interface: Any
Outbound Interface: Any

sonicwallは、接続しようとする外部サービスを認識し、サーバー内部のアドレスに合わせて宛先アドレスを書き換えます。したがって、それはコンピューターに対して透過的です。


-2

PFを使用するFreeBSDでは、次のように簡単です(pf.confファイルで):

extif = "tun0"
intif = "em0"
{other rules}...
nat on $intif from any to 192.168.20.8 port 80 -> ($extif)

192.168.20.8が内部Webサーバーになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.