NATを越えろ

自宅のデスク周りを充実させまくったら、部屋から完全に出不精になってしまいました。

ビデオ会議をする機会が大分増えてきて、今後もビデオチャットで仕事をすることや、プライベートでも活用の幅がふえてくるのでは?ということでせっかくなので※1 WebRTCでビデオチャットを実装した際にNATについて色々学びがあったのでここでアウトプット。

※1. Web RealTime Communicationの略でブラウザで気軽にリP2P通信ができるようにしたもの(オープン標準技術)

以下WebRTCのプロトコルスタック
主に赤枠の部分についての話

図:オライリー

そもそもNATってなんやねん

NAT(Network Address Translation)とは、コンピュータネットワークにおいて、主にグローバルIPアドレスをプライベートIPアドレスに、またはその逆の変換を行う技術のことである。

by wikipedia

つまりプライベートアドレスをグローバルアドレスに変換してインターネット上のアドレスとやりとり出来るようになる

ローカルネットワークとグローバルネットワークを行き来するための仕組み

静的・動的?

静的NAT

グローバルアドレスとプライベートアドレスを1対1の固定ペアとして変換を行う

動的NAT

外部への通信が発生したときに、プール内のグローバルアドレスを使用して変換を行う

NAPT(動的)

NAPT(Network Address Port Translation)とは、アドレスに加えてポート番号も変換する技術。
グローバルアドレスがひとつの場合でも、動的に割り当てられた送り元Portと送り先Portを元に関連付けを行うことができる。

家や会社で一つのグローバルIPで同時にインターネットができるのはこの仕組みのおかげ

送り元IP:送り元ポート.送り先IP:送り先ポート内容で接続ごとに管理している

NATタイプ

Full cone NAT(フルコーンNAT)

送信したことがないアドレスでも受信可能
※UPnPのポートマッピングはほぼこれに該当する

Address-Restricted cone NAT(制限付きコーンNAT)

一度送信した端末(NATデバイス上にWAN側に送信先アドレスのエントリが存在する場合)であれば受信可能

Port-Restricted cone NAT(ポート制限付きコーンNAT)

一度送信した端末(NATデバイス上にWAN側に送信先アドレスと送り元Portのエントリが存在する)であれば受信可能

Symmetric NAT(対象型NAT)

対象型NATは最も制限の厳しいもので、宛先アドレスとポートを用いて接続先を区別し、一つの接続先に対し一つのアドレス変換を用いる

Nat traversal(NAT越えの手法)

以上をふまえると(ふまえなくても)NATを越えるのがいかに難しく、不確定要素が多いのかが分かります。。。

人様のPCに外部から接続なんで冷静に考えたら厳しいのは当たり前ではあるのですが(; ・`д・´)

NATを越えるためにいくつか手法として、ルーターで対応してるもの(UPnP)や、connection reversalなどがありますが、
WebRTCで利用されるSTUNという仕様があり、その中で利用されているUDP hole punchingについてちょっと触れてみた。

UDP hole punching

上記Cone型による接続を行う際にファイヤーウォールとかどうやって突破すんねんって疑問が沸くかと思いますが、
それをうまいことするのがこのUDP hole punching。

上記の仕組みを使うことで、NAT外サーバー(STUN SERVER、SIGNALING SERVER)を経由してアドレス交換を行い、NAT内ホスト同士をNAT外から通信の開始を可能にしている。

まとめ

今回は触れませんでしたが、Peer間で最適な通信方法(STUN, TURN)の交渉にICEという仕組みがあったりとか、
STUNで越えられない場合の最終手段TURNなども今回ビデオチャットを実装する上で軽く触れましたが、割愛させていただきます(*´з`)

最後に、本技術を駆使して以下プロダクトを作りましたのでよろしければ!