Open8

NATから理解するネットワークの仕組み

huskyhusky

リサーチの背景

通信プロトコルの新しい規格として、Googleが提唱する「QUIC」がTCPをリプレイスする可能性が出てきています
QUICはQuick UDP Internet Connectionsの略で、その名の通りUDPをベースとした規格ですね

Googleがすでに、QUICをHTTP/3としてChromeに導入を進めていることを発表しているので、もうすぐQUICが通信プロトコルとして標準化されるのも近そうです
Chrome is deploying HTTP/3 and IETF QUIC

https://blog.chromium.org/2020/10/chrome-is-deploying-http3-and-ietf-quic.html

それに伴って、通信手法の新しいげ概念が増えてきそうなので、改めて現状の通信規格を振り返りつつ、NATの基礎をまずはメモ程度にスクラップしていきます!

huskyhusky

そもそもNATってなんだっけ

ある程度ネットワークについて触れ照れば、NAT越え(NAT Traversal)というキーワードは目にしたことがありますよね
一言で言えばNATは、デバイス⇄インターネット⇄デバイス(サーバーなど)で通信をする際に、パケット(送りたいデータの一部)のIPアドレスを双方向通信ができるよう、うまく調整してくれる機能です

  • インターネット上でアクセス可能なIPは、グローバルIPアドレスに分類される
  • インターネット上から誰でもアクセスできないIPは、プライベートIPアドレスに分類される

NATが通信する際に必要な理由は👆このIPアドレスの違いを "翻訳" している感じの理解で一旦はOKです

huskyhusky

NATの種類

NATは、静的・動的であるか、またSymmetric・Cone型であるかで分類をすることが可能です。

  • 静的: NATを通り抜けられるIPアドレスを事前にConfigファイルに書き込んでおくやり方
  • 動的: NATに対してリクエストがあるたびに、それぞれのIPアドレスをキャッシュしておくやり方
  • Symmetric型: リクエスト先のIPアドレスごとに、独自のIPアドレスを設定し記憶(動的であれば)しておくやり方
  • Cone型: プライベートIPとNATが一度変換した情報がある限り、パブリックIPアドレス側からNATを通してプライベートIPに通信可能なやり方

Symmetric型とCone型の大きな違いは、NATが持つ テーブル にあります。

Symmetric

IPインバウンドフィルター IP/Port コンビネーション
送信先のIPをキャッシュ 送信元⇄NAT変換後のIPとPortの組み合わせをキャッシュ

Cone

IPインバウンドフィルター IP/Port コンビネーション
送信先のIPはキャッシュしない(インバウンドIPに依存しない) 送信元⇄NAT変換後のIPとPortの組み合わせをキャッシュ
huskyhusky

Cone型 NATの種類

Cone型では、送信先のIPに依存せずNAT変換後のIPへの通信は送信元へ通信が可能と書きました。
ただ、Cone型においても完全にフィルタリングをしない訳ではなく、3通りのケースが存在しています。

  • Full Cone NAT: ゼロフィルター状態。グローバルIPからIP/Portコンビネーションが存在するNATにパケットが届くと通信が通る。
  • Adress Restricted Cone NAT: 1度でもプライベートIPからグローバルIPへ送信した履歴がある&送信元⇄NAT変換後のIPへパケットが届くと通信が通る。
  • Port Restricted Cone NAT: 1度でもプライベートIPからグローバルIPへ送信した履歴がある&送信元⇄NAT変換後のIP/Portへパケットが届くと通信が通る。
huskyhusky

NATを補う STUN & TURN & ICE

NATを通した通信では、相手のIPアドレス or NATによるIPアドレス変換情報を必ずグローバルサーバー(クライアント)側が知っておく必要があることがわかりました。
ただ、双方向通信の間にNATが存在しているだけでは、どう頑張ってもNATが持つIPやぽrtのペア情報を引き出すことはできません。

そこで登場するのが、STUN、TURN、ICEと呼ばれるものです。

STUN

  1. プライベートIPのクライアントから、STUNサーバーに通信リクエストを送る
  2. STUNサーバーにたどり着くまでにNATを通るので、IPの組み合わせが登録される
  3. STUNサーバーは変換後のNATが生成したIPアドレスは知っている!!
  4. 本来の通信相手はSTUNサーバーに(3)のIPアドレスをQueryなどで聞き出す
  5. (4)で得たIPアドレスを元に通信リクエストを送れば、あとはNATが送信元のIPへと自動で変換するので通信は成功する

TURN

送信元・送信先の間に入ってパケットをリレーする役割。
お互いNATを通して共通のTURNサーバーに通信リクエストを送ることで、パケットの交換が可能になります。
一見、簡単に見えるけどインターネット上にTURNサーバーは存在しないので、例えば自社システム上に構築することが前提となっていますね。

ICE

一言で表現すると、STUNとTURNをいい感じに使い分けてくれるもの。

huskyhusky

Cone型NATの復習

通信時に,ルーターはパケット送信元のPrivate IPとPortをキャッシュします。ただし,WANに対して接続するためにはPrivateな状態からPublicに変換させてあげる必要があります。それが,NATの役割でした。
こうすることで,Public側のデバイスが自由にNATのWAN側アドレスに対してパケットを送信することで,該当するPrivate IPとPortを持つ場所にマッピングさせることが実現できます。

上記では,NAT側のPublic IPが既知であるという条件のもと,話が進んでいました。しかし,実世界では,通信したいと思う相手側のIPとPortを何もせずに知ることはできません。
例えていうなら,お互いが違うマンション(IPアドレス)のある部屋(Port)にいずわりながら,マジックのように相手の住所を知ることはできないですよね。これと概念は全く一緒です。

では仮に,相手との連絡手段がどこかで確立していたらどうでしょうか?例えば相手のMessengerを知っていて,そこから相手へメッセージを送ることで相手の住所を聞き出すことは当たり前ですが可能ですよね。これを,Cone NATを介して実現するのを UDP Hole Punching と呼びました。

UDPで事前にお互いのPublic側NATのIPとPortをサーバーに送信し,情報を交換しておきます。(Messengerを通してお互いの情報を得る)
こうすることで,正しいNATとPortの組み合わせに対してパケットを送信することができるようになります。

huskyhusky

Cone型NATの復習 ~ 越えられないNAT ~

NATはMessengerを介して,事前にコミュニケーションを図っておけば無事メッセージを送れることがわかりました。しかし,NATの種類によっては,Messengerを介してではなく,直接手紙をやりとりした相手でないと受け付けない!!とルール付けがされているものが存在します。

それが,Address Restricted NATPort Restricted NATでした。前者は,IPアドレスのみを制限していて,後者はIPアドレスもPortも制限範囲に含められています。

これは,前者が特定の国から手紙を今までに受け取ったことがあれば(NATテーブルにIPアドレスが存在する),今回の手紙を受け取る(パケットがNATを越える)と言い換えることができます。後者は,より制限がきつく,特定のマンションかつ特定の部屋への送信履歴(NATの内側から)がない限りパケットはNATを越えない条件となっています。