NATはどの接続がインバウンドで、どの接続がアウトバウンドであるかをどのように決定しますか?


7

NATの背後にあるノードにアクセスできる必要があるP2Pアプリケーションを構築しています。このNATはインバウンド接続を許可しないため、ネットワーク外部のノードは、NATの背後にあるノードに到達できません。

この問題に対する私の解決策は、NATの背後にあるノードが外部のノードに到達し、外部のノードが時間の準備ができたら、事前に確立されたTCP接続を使用して、NATの内部にあるノードに接続することです。この接続はNAT内のノードによって確立されるため、NATによってブロックされることはありません。

これが私の質問です。下線が引かれた解釈のうちどれが正しいのか、または両方が間違っているのかはわかりません。

解釈#1

そこ効果的にTCP接続、チューブの概念は、およびNATの内側のノードが外の世界に何かを要求する際に、そのチューブが開き、応答がそれに入れられ、そしてチューブは永遠に閉じます。

結果:そのチューブが閉じた後、NATは外部ノードからクライアントへのそれ以上のTCP接続を許可しません。

解釈#2

TCP接続などはありませんが、TCP送信です。TCP接続はlocal ip:port、およびとして定義されているため、remote ip:portNATの背後のノードが外部のノードを呼び出した後、外部のノードは、クライアントが要求を行ったのと同じポートを使用してコールバックでき、同じTCPとして「カウント」されます。接続によるもので、NATによる一方的な呼び出しではありません。

結果: NATは、この接続が、NAT内のノードが履歴レコードを調べることによって要求したものに対する応答であったかどうかを効果的に推測します。NATの背後にあるノードが最初のコールアウトを行ったので、外部のノードは同じクライアントポートを使用してコールバックでき、機能します。

私のメンタルモデルは#1に近かったのですが、Wiresharkで接続を調べたところ、それらは個別のTCP接続として、または少なくとも個別のエンティティとして表示されました。

#1、または#2に近いですか、それとも混乱してしまいますか?


STUNと関連する作業を調べたい場合は、en.wikipedia.org
wiki

5
最初のバージョンで複雑なNATをすべて処理する必要がないように、最初にアプリケーションのIPv6バージョンを実装することを強くお勧めします。IPv6で動作するバージョンを入手したら、IPv4で動作させる方法を検討してください。
kasperd

回答:


9

TCPは接続指向のプロトコルであり、接続を介してのみ通信できます。

TCPを使用してプログラミングを開始する前に、TCPがどのように機能するかを最初に理解しておくと役に立ちます。TCP の定義であるRFC 793、Transmission Control Protocolから始める必要があります。

RFCはソケットと接続について説明しています。

多重化:

単一のホスト内の多くのプロセスがTCP通信機能を同時に使用できるようにするために、TCPは各ホスト内にアドレスまたはポートのセットを提供します。これは、インターネット通信層からのネットワークおよびホストアドレスと連結され、ソケットを形成します。ソケットのペアは、各接続を一意に識別します。つまり、ソケットは複数の接続で同時に使用できます。

プロセスへのポートのバインドは、各ホストによって独立して処理されます。ただし、頻繁に使用されるプロセス(「ロガー」やタイムシェアリングサービスなど)を、一般に公開されている固定ソケットにアタッチすると便利です。これらのサービスには、既知のアドレスを介してアクセスできます。他のプロセスのポートアドレスの確立と学習には、より動的なメカニズムが含まれる場合があります。

接続:

上記の信頼性およびフロー制御メカニズムでは、TCPが各データストリームの特定のステータス情報を初期化および維持する必要があります。ソケット、シーケンス番号、ウィンドウサイズなどのこの情報の組み合わせは、接続と呼ばれます。各接続は、その両側を識別する1組のソケットによって一意に指定されます。

2つのプロセスが通信する場合、それらのTCPは最初に接続を確立する必要があります(両側のステータス情報を初期化します)。それらの通信が完了すると、接続が終了またはクローズされ、リソースを他の用途に解放します。

信頼できないホスト間および信頼できないインターネット通信システム上で接続を確立する必要があるため、接続の誤った初期化を回避するために、クロックベースのシーケンス番号を持つハンドシェイクメカニズムが使用されます。

外部TCPピアに関しては、デバイスが内部デバイスによって開始された接続に基づいて、内部の別のTCPピアに転送している場合でも、NATデバイスの外部アドレスに接続しています。

RFC 5382、NAT Behavioral Requirements for TCPも学習できます


7

TCP接続は、どちらかの端のソフトウェアプロセスがソケットを開いたままにしている限り、「有効」であると見なされます。

一方または両方のプロセスがソケットを閉じると(正常に接続されるか、何らかの理由で接続が中止されます)、これにより、回線上でFINまたはRSTフラグが設定されたTCPパケットに変換されます。

NATルーターのNAT実装は、FINフラグとRSTフラグを探し、これらのフラグを持つパケットを検出すると、「穴をふさぎます」。この後、クライアントは「新しい穴を開ける」ために新しい接続を開始する必要があります。

要約すると、クライアントとサーバーがソケットを開いたままにしている限り、NATアソシエーションは存続します。


4

ここで「通常」と書いているとき、私はあなたの平均的な消費者向けWLAN-NATルーターを正気な構成で、またはデフォルト設定でいくつかの単純なLinuxネットワークを考えています。いつものように、これは必要に応じて複雑または複雑にすることができます。質問は非常に基本的なので、これは、より複雑なエンタープライズレベルのNATソリューションに直接進むのではなく、私にとって最も理にかなっているようです。

あなたはすでに回答を受け入れましたが、あなたが尋ねた質問に直接答えることを試みましょう:

NATはどの接続がインバウンドで、どの接続がアウトバウンドであるかをどのように決定しますか?

決定の基礎(ルーターでの決定の場合)は、何らかの形式または形式の一連のルールです。この場合、関係する各インターフェース(つまり、内部LANインターフェースと外部WAN /アップリンクインターフェース)に対して、管理者はルールを実装します。これらのルールはかなり異なります。つまり、LANインターフェースのルールは、WANインターフェースのルールとは大きく異なります。

パケットがどこから来てどこに行くかを知ることは、ルーターが行うことの基本です。

から始めましょう

ウィキペディアのNATページには、この問題に関する多くのテキストがありますが、単純なケース(単純な企業LANと単一のDSLアップリンク)は、次のようになります。

  1. クライアントPCは、インターネットベースのサーバー(例:198.51.100.20)へのHTTP接続を開始しようとします。PC自体には、192.0.2.2のような非ルーティングアドレスがあります。安価なDSLルーターには2つのインターフェースがあり、1つは内部(192.0.2.1)と1つは外部(203.0.113.10、頻繁に変更され、DLSプロバイダーによってローカルリンクプロトコルを通じて提供される)です。そのため、PCはデフォルトゲートウェイ(192.0.2.1)を介してSYNパケットを198.51.100.20:80に送信します。
  2. ルーターは、NATがまったく関与していない場合と同様に、インターフェイス192.0.2.1でパケットをピックアップします。このインターフェイスでNATを実行するように構成されているため、次のことを実行します。
    • これまで使用されていない新しいポート番号を作成します。例:12345。
    • IPヘッダーの「送信者」アドレスを203.0.113.10に変更します。
    • (PCから提供される)TCPヘッダーの元の送信者ポート番号を覚えて、4321と呼びましょう。
    • 12345送信者ポート番号を含むようにTCPヘッダーを変更します。
    • NAT変換テーブルにエントリ(12345; 192.0.2.2; 4321)を追加します。
    • 陽気な方法でパケットを独自のアップリンク/ゲートウェイに送信します。
  3. 198.51.100.20は最終的にパケットを受信し、それがSYN(「新しい接続の確立」)であることを認識して、SYN-ACKメッセージを送信者に送り返します。その観点から、これは123.0のTCP宛先ポートを持つIPアドレス203.0.113.10です。
  4. ルータは、WANインターフェイスでこのパケットを受信します。WANインターフェースは、このようなNATされたアドレスを解決するように構成されています。次にルーター...
    • ... NAT変換テーブルをチェックし、エントリを見つけます...
    • ...パケットを宛先192.0.2.2に変更します...
    • ... TCP宛先ポートを4321に戻します...
    • ...そして(LANインターフェース上で)陽気な方法で送信します。
  5. PCはパケットを受信し、NAT手順について何も表示しません。パケットルックスだけ NATルータがすべてではありませんでしたかのように198.51.100.20が、それを送っていた場合などです。

「接続」のトピックはまったく表示されません。(最も単純な形式の)NATルーターは、メッセージの内容を気にする必要はありません。これは、送信者と受信者のIPアドレスとポートについてのみ考慮します。(許可:これは、セキュリティおよびパフォーマンス関連のあらゆる種類の問題をスキップしている可能性がありますが、これは、この質問で手元にあるような非常に基本的な原則に関するものです。)

では、ルーターはどのようにして知るのでしょうか?

ルーターは「接続」についてまったく知る必要がありません。実際、TCPの場合と同様の手順は、コネクションレス型UDPプロトコル(UDPホールパンチング)にも存在しますが、実際には、トランスポート層にポート番号のようなものがあるプロトコルに実装できます。

ルータがNATに関してトランスポートレベルのプロトコル(TCP、UDPなど)を知る必要があるのは、主にポート自体がIPの一部ではないためです。ポートは、(この種の)NATを簡単に可能にする「ハック」を作成するものです。

だから、あなたの質問に:

NATはどの接続がインバウンドで、どの接続がアウトバウンドであるかをどのように決定しますか?

アウトバウンド接続は、LANインターフェースに現れるSYNパケット(UDPの場合は最初のUDPパンチ)で始まる定義ごとの接続です。NATの場合、それらを「接続」と呼ぶことは少し多くなります。これらは、NAT変換テーブルの一時的なエントリ(および個々のNATルーターが採用する可能性のあるセキュリティ/パフォーマンスの追加)として単純に終了します。

これまでの回答で使用したシナリオには、インバウンド接続はありません。もちろん、これを行うNATのバリエーションがあります。たとえば、ルーターのWANインターフェース上のポートを、LANインターフェース上の特定のIP:PORTで静的に識別できるため、NATされたLAN内でサーバーを実行できます。これは、安価なコンシューマーDSL / WLANルーターでもサポートされています。また、「実際の」ルーターを使用すると、好きな形式や方法でルーターを構成できます。

以降のインバウンド/アウトバウンドIPパケットは、例で示したものと変わりません。最初のSYNハンドシェイクが完了し、ルーターの変換テーブルにエントリがあると、双方向のすべてのパケットが(例で説明したのと同じ変換で)通過します。

このように確立されたTCP接続のコンテキストで、サーバーがクライアントにデータを送信したい場合(完全に可能です-TCPは双方向です)、NATルーターに関する限り、これらは単なるIPパケットです。これらのパケットの内容については、それほど気になりません(つまり、特定のペイロードが含まれているか、TCPの「管理」パケットであるかなど)。

ルーターを置くときに、ルーターが「チューブを閉じる」ことはありません。明らかに、ルーターはいつ変換テーブルからエントリをクリアできるか(おそらく、接続を終了するFINハンドシェイクに気付いたとき、またはタイムアウトやエラー状態によって)の概念を持っていますが、最初から最後までは1つの継続的な事件。


1
特にGoogleからの有効なアドレスを「ハイジャック」するのではなく、文書化の目的で特別に定義されたRFC5737のIPアドレスを使用してください。
Patrick Mevzek

1
接続は双方向であるため、インバウンドとアウトバウンドの両方です。着信または発信の接続の開始です。
Ron Maupin

@RonMaupin、はい、私は最後の段落で、特に最後から2番目の段落で説明します。それはあなたが意味したことと一致しますか、それとも不明瞭な方法で書いたのですか?
AnoE

@PatrickMevzek、毎日何か新しいことを学びましょう。完了+ありがとう!
AnoE

ありがとう。同意します。私の質問は、より具体的には、全体的な双方向性に関する質問としてではなく、接続の開始として表現されます。私はすでにポートマッピングを実装しており、正常に動作するルーターが機能します。私はこの質問をして、コーヒーショップや公共の場所など、共同作業を行わないルーターに何ができるかを理解しました。これは全体的な状況を乗り越える素晴らしい応答ですが、非常に高く評価されています。
ディーンM.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.