STUN Server は、Session Traversal Utilities for NAT(STUN)プロトコルのサーバーであり、クライアントが自身の外部IPアドレスとポートを特定し、さらに自身が位置するNetwork Address Translation(NAT)の種類を判別できるようにします。IETF RFC 5389、2008によると、STUNはWebRTCインフラストラクチャの必須コンポーネントであり、NATの背後にあるクライアント間の直接ピアツーピア接続を確立します。
重要なポイント
STUN Server(Session Traversal Utilities for NAT)は、RFC 5389で定義されRFC 8489で更新されたプロトコルで動作するネットワークサービスです。STUNサーバーの主なタスクは、クライアントに外部ネットワークから見える自身のパブリックIPアドレスとポートに関する情報を提供し、クライアントとインターネットの間にあるNATデバイスの種類を特定することです。
STUNアーキテクチャには2つのコンポーネントがあります。アプリケーション(ブラウザやネイティブWebRTCアプリなど)に組み込まれたSTUNクライアントと、パブリックネットワークに配置されたSTUNサーバーです。クライアントはサーバーにBinding Requestを送信し、サーバーは応答でリクエストの送信元IPアドレスとポート、つまりサーバーから見たクライアントのパブリックアドレスを返します。このデータをローカルアドレスと比較することで、クライアントは自身のネットワークで使用されているNATの種類を特定できます。
STUNはUDP(デフォルトポート3478)またはTCP(ポート3478、TLSの場合は5349)上で動作します。STUNメッセージは20バイトのヘッダーと可変数の属性で構成されます。ヘッダーにはメッセージタイプ(Binding Request、Binding Response、Binding Error Response)、長さ、リクエストとレスポンスを対応付けるための一意のトランザクションID(96ビット)が含まれます。各Binding ResponseにはXOR-MAPPED-ADDRESS属性(クライアントの外部アドレス)が含まれ、STUNトラフィックの傍受に基づく攻撃から保護するためにマスキング付きでエンコードされています。
STUNサーバーはシンプルなリクエスト-レスポンスプロトコルで動作します。NATの背後にあるクライアントはBinding Requestを作成し、STUNサーバーに送信します。サーバーはパケットを受信し、UDPヘッダーから送信元IPアドレスと送信者のポートを抽出し、Binding Responseを作成して、このアドレスをXOR-MAPPED-ADDRESS属性にパッケージ化します。レスポンスはリクエストの送信元アドレスに返送されます。
クライアントはレスポンスを受信し、NATデバイスによって割り当てられた外部IPアドレスとポートを含むXOR-MAPPED-ADDRESSを抽出します。次にクライアントはこのアドレスを自身のローカル(RFC 1919 — プライベート)アドレスと比較します。アドレスが一致する場合、クライアントはNATの背後にありません。異なる場合、クライアントはNATの背後にあり、外部アドレスはWebRTCのICE(Interactive Connectivity Establishment)の候補として使用されます。
STUNサーバーはテストリクエストのシーケンスを通じてNATの種類を特定できます。クライアントは異なるフラグ(CHANGE-REQUEST)を付けてリクエストを送信し、応答を分析します。完全な検出サイクルには、STUNサーバーの異なるIPアドレスとポートへのリクエスト送信が含まれます。サーバーが変更されたポートのリクエストに応答する場合、NATはRestricted Coneタイプです。変更されたポートとIPのリクエストに応答しない場合、NATはSymmetricタイプです。この情報はWebRTCでICE戦略を選択するために重要です。
STUNサーバーは4つの主要なNATタイプを検出でき、それぞれがP2P接続を確立する能力に異なる影響を与えます。NATタイプは、STUNが2つのクライアント間の直接接続を可能にできるかどうかを決定します。また、接続に使用されるICE候補(host、server reflexive、relay)も決定します。
| NATタイプ | 動作 | STUNの動作 | ICEフォールバック |
|---|---|---|---|
| Full Cone | 任意の外部ホストがクライアントにパケットを送信できる | はい | Server Reflexive |
| Restricted Cone | クライアントがパケットを送信したホストのみ | はい | Server Reflexive |
| Port Restricted | Restrictedと同様だが、送信元ポートでもフィルタリング | はい | Server Reflexive |
| Symmetric NAT | 外部アドレスはホスト:ポートのペアごとに一意 | いいえ | Relay(TURN) |
Symmetric NATはSTUNが対応できない唯一のタイプです。Symmetric NATでは、新しい宛先ホストへの新しいリクエストごとに異なる外部アドレス(IPやポート)が割り当てられます。STUNサーバーはSTUNサーバー自体への接続のアドレスを報告するため、このアドレスは別のクライアントへの接続には使用できません。このような場合、WebRTCはトラフィックを中継するためにTURNサーバーを使用します。調査によると(Ford et al.、RFC 3489、2003)、インターネット上の全NATデバイスの約8〜10%が対称型です。
STUNサーバーはRTCPeerConnection設定を通じてWebRTCに統合されます。ブラウザまたはネイティブアプリケーションはSTUNを使用してICE候補を収集し、その後Signaling Serverを介して交換されます。WebRTC設定では、STUNサーバーはiceServers配列でUDPの場合はstun:プレフィックス、TLS接続の場合はstuns:プレフィックスで指定されます。
WebRTCアプリケーション用にRTCPeerConnectionを作成する際の、JavaScriptでのSTUNサーバー設定の例を見てみましょう。
const config = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302"
},
{
urls: "stun:stun1.l.google.com:19302"
}
]
};
const pc = new RTCPeerConnection(config);
pc.onicecandidate = (event) => {
if (event.candidate) {
console.log("ICE候補:", event.candidate.candidate);
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
この例ではGoogleのパブリックSTUNサーバー(stun.l.google.com:19302)を使用しています。offerまたはanswerを作成する際、ブラウザは自動的に指定されたサーバーにSTUN Binding Requestを送信し、外部アドレス(server reflexive候補)を取得してICE候補リストに追加します。すべての候補が収集された後、Signaling Serverを介してリモートピアに送信され、直接P2P接続の確立を試みます。
ICEプロセスには3つの候補タイプがあります。host(ローカルアドレス)、srflx(server reflexive — STUNから取得)、relay(TURNを介して中継)です。STUNサーバーはsrflx候補の作成を可能にします。srflx候補はrelay候補よりも優先度が高くなります。STUNベースの接続は直接接続であり、中継を必要としないためです。ICEプロセスは両方のピアのすべての候補の組み合わせ(ローカルおよびSTUNから取得)をチェックし、最も優先度の高いものから開始します。
STUNサーバーにはプロトコルアーキテクチャに関連する基本的な制限があります。主な制限は、外部ホストへの新しいリクエストごとに一意の外部ポートが割り当てられるSymmetric NATで動作できないことです。この場合、STUNサーバーから取得したアドレスは、NATがSTUNサーバー自体との通信のためだけにバインディングを作成したため、別のピアへの接続に使用できません。
2つ目の制限は、STUNはデータ中継を提供しないことです。直接P2P接続が不可能な場合(両方のピアがSymmetric NATの背後)、STUNはデータ送信の代替パスを提供しません。この場合、TURNサーバーが必要です。TURNサーバーはピア間のメディアトラフィック中継として機能し、一方の参加者からデータを受信し、自身のパブリックIPアドレスを介して他方に送信します。
制限があるにもかかわらず、STUNサーバーはWebRTCインフラストラクチャの重要なコンポーネントであり続けています。ほとんどの場合(80〜90%)、STUNを使用して直接P2P接続を確立でき、TURN中継のコストを回避し、メディアデータ送信の遅延を削減できます。パブリックWebRTCアプリケーションでは、自動フォールバック付きでSTUNサーバーとTURNサーバーを組み合わせて使用することをお勧めします。
よくある質問
STUNサーバーはインターネット上の「鏡」であり、クライアントに自身の外部IPアドレスを伝えます。コンピューターがルーター(NAT)の背後にある場合、自身のパブリックアドレスを知りません。STUNサーバーはそれを特定するのを助け、他のコンピューターが直接接続できるようにします。
WebRTCでは、STUNサーバーはRTCPeerConnection設定で指定されます。ブラウザは外部候補アドレス(srflx)を取得するためにSTUNリクエストを送信します。この候補はSignaling Serverを介してリモートピアに渡され、ICEがそれらの間の直接接続を確立しようとします。
STUNは直接P2P接続のための外部アドレスを見つけるのに役立ちます。TURNはP2Pが不可能な場合に自身のサーバーを介してトラフィックを中継します。STUNは「鏡」、TURNは「仲介者」です。TURNはサーバーに負荷をかけ、遅延を追加するため、STUNが優先されます。
Googleは無料のSTUNサーバーを提供しています:stun.l.google.com:19302、stun1.l.google.com:19302。TwilioもNetwork Traversal Serviceを通じてSTUN + TURNインフラストラクチャを提供しています。本番アプリケーションでは、可用性が保証された独自のまたは商用のSTUN/TURNサーバーを使用することをお勧めします。
Symmetric NATは、「ローカルアドレス:宛先外部アドレス」のペアごとに一意の外部ポートマッピングを作成します。クライアントがSTUNサーバーから受け取るアドレスは、そのSTUNサーバーとの接続に紐づいています。別のピアがこのアドレスを使用しようとすると、Symmetric NATはパケットをブロックします。新しい宛先アドレスではポートマッピングが異なるためです。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。