WebRTCの接続確立(ICE/STUN/TURNとシグナリング)
ブラウザ同士をP2Pで直結し低遅延な音声・映像・データ通信を実現できる。ICE候補収集とSTUN/TURNによるNAT越え、SDPシグナリング、DTLS/SRTP暗号化の流れを原理から理解できる。
- 1.WebRTCはメディア/データ経路をP2Pで張るが、相手のIP・コーデック・暗号鍵を交換する経路(シグナリング)は規格外で、開発者が別途用意する。
- 2.ICEは到達可能なアドレス候補(host/srflx/relay)を集め、両端でペアを総当たりして接続性チェックを行い、最良の1経路を選ぶ。STUNが自分の外側アドレス発見、TURNが中継を担う。
- 3.メディアはDTLSハンドシェイクで鍵交換し、その鍵でSRTPを暗号化する。DTLSの証明書指紋をSDP経由で検証することでMITMを防ぐ。
WebRTCが解く難問
WebRTCはブラウザ同士をサーバーを介さずに直結し、音声・映像・任意データを低遅延でやり取りする枠組みです。しかし現実のインターネットでは、両端がほぼ確実にNAT(Network Address Translation)の内側にいます。プライベートIPしか持たないブラウザ同士が、互いの「外から到達できるアドレス」を知らないまま直接つながることはできません。
WebRTCの接続確立は、このNAT越えを中心に据えた一連の手順です。大きく分けて「相手の情報を交換するシグナリング」「到達経路を探すICE」「経路を暗号化するDTLS/SRTP」の3層からなります。重要なのは、WebRTCが標準化したのはメディアとデータの経路だけで、その前段の情報交換は規格外という非対称性です。
シグナリングは規格外
P2Pを張る前に、両端は最低限「相手のアドレス候補」「使えるコーデック」「暗号鍵の指紋」を交換する必要があります。この交換がシグナリングですが、WebRTCはそのプロトコルをあえて規定していません。WebSocket・HTTP・任意のメッセージ基盤、何を使ってもよい設計です。
交換される本体は**SDP(Session Description Protocol)**というテキスト形式の記述で、offer(発信側)と answer(応答側)を1往復します。
発信者A シグナリングサーバー 応答者B
| createOffer() で SDP offer 生成 | |
|---- offer 送信 ----------------------->|---- offer 中継 ------>|
| | setRemoteDescription |
| | createAnswer() |
|<--- answer 中継 ------------------------|<--- answer 送信 -------|
| setRemoteDescription | |
SDPには、メディア種別(m=audio / m=video / m=application)、コーデックと優先順位、後述するICE候補や認証情報(ice-ufrag / ice-pwd)、DTLS証明書の指紋(a=fingerprint)が含まれます。
アプリごとに認証・ルーム管理・通知の事情が大きく異なるため、規格で縛るより既存の仕組みに載せる方が現実的だからです。逆に言えば、シグナリング経路の認証と完全性は開発者の責任です。ここが乗っ取られると後述の指紋検証も無意味になり得るため、TLSで保護したチャネルを使うのが前提になります。
ICE候補の収集
シグナリングで土台ができたら、**ICE(Interactive Connectivity Establishment、RFC 8445)**が実際の経路を探します。まず各端末が、自分宛てに使えそうなアドレス候補を列挙します。候補は到達性の高さ順に3種類あります。
| 候補タイプ | 意味 | 得る方法 |
|---|---|---|
| host | 端末が持つローカルIP(LAN内アドレスなど) | OSのネットワークインターフェースから直接列挙 |
| srflx(サーバー再帰) | NATの外側から見た自分のIP・ポート | STUNサーバーに問い合わせて返答から判明 |
| relay(中継) | TURNサーバー上の中継アドレス | TURNサーバーに割り当てを要求して確保 |
host 候補は同一LAN内なら最速ですが、NAT越しでは届きません。そこでSTUN(Session Traversal Utilities for NAT)サーバーに「私のアドレスはどう見える?」と尋ねます。STUNは受信パケットの送信元、すなわちNATが書き換えた後の外側アドレスをそのまま返すだけの軽量サーバーです。これで得るのが srflx 候補で、多くのNAT環境ではこれだけで直接P2Pが成立します。
TURNによる中継
srflx でも越えられないNATが存在します。代表が**対称型NAT(symmetric NAT)**です。対称型NATは「宛先ごとに異なる外側ポートを割り当てる」ため、STUNサーバー宛てに開いた穴と、相手ブラウザ宛ての穴が一致しません。STUNで得たアドレスへ相手が送っても届かないのです。
このとき最後の砦が**TURN(Traversal Using Relays around NAT)**です。TURNサーバーは両端の中間に立ち、すべてのメディアを中継します。各端末はTURNサーバーへ外向きに接続を張る(=自分のNATには穴が開く)ため、対称型NAT同士でも疎通します。
TURNは全トラフィックがサーバーを経由するため、P2Pの利点である低遅延と帯域削減が失われ、サーバーの転送コストもかかります。ICEは可能な限り直接経路(host/srflx)を優先し、relayは他が全滅したときだけ選びます。実運用では「数割の接続はTURNに落ちる」前提で、TURNサーバーの帯域を見積もる必要があります。
接続性チェックとペア選定
候補が出そろうと、ICEは自分の候補×相手の候補であらゆる組み合わせ(候補ペア)を作り、優先度順に並べます。そして各ペアについて、STUNの仕組みを使った**接続性チェック(connectivity check)**を双方向に行います。
1. ローカル候補とリモート候補の全ペアを生成
2. 優先度(候補タイプ・ポート等から算出)で降順ソート
3. 各ペアへ STUN Binding Request を送り、応答が返るか確認
4. 双方向で応答が成立したペアを「有効」と判定
5. 最も優先度の高い有効ペアを選んで通信に採用(昇格)
このチェックの送受信そのものが、NATに戻りパケット用の穴を開ける役割も果たします(ホールパンチング)。候補は一度に全部出さず、見つかり次第シグナリング経由で相手へ追加送信できます。これがTrickle ICEで、収集の完了を待たずチェックを並行させ、接続確立を早めます。一致するペアが1つも無ければ接続は失敗します。
ICEの優先度は「より直接的な経路ほど高い」よう設計され、概ね host > srflx > relay の順です。RFCでは type preference という係数で各タイプに既定の重みが与えられます。試験では「STUN=外側アドレス発見(直接路を助ける)/TURN=中継(最終手段)」「対称型NATではSTUNが効かずTURNに落ちる」を押さえると判別を誤りません。
DTLSとSRTPによる暗号化
経路が決まっても、流すデータは暗号化が必須です。WebRTCはメディアの暗号化を仕様で義務化しており、平文通信はできません。鍵交換にはDTLS(Datagram TLS)を使います。TLSをUDP上で動くようにしたもので、選定された経路上でDTLSハンドシェイクを行い、共有鍵を確立します。
ただしメディア本体はDTLSで包むのではなく、DTLS-SRTPという方式で、DTLSハンドシェイクで得た鍵素材を使って**SRTP(Secure RTP)**の鍵を導出します。以後の音声・映像パケットはSRTPで暗号化・認証されます。DataChannel(任意データ)の場合はSCTPをDTLS上で直接流します。
ここで肝心なのが中間者攻撃(MITM)への耐性です。DTLSは自己署名証明書を使うため、証明書だけでは相手を信頼できません。そこで各端末は自分のDTLS証明書の指紋(ハッシュ)をSDPの a=fingerprint に載せ、シグナリング経由で相手へ渡します。ハンドシェイク時に提示された証明書の指紋がSDPの値と一致するかを検証することで、「シグナリングで合意した相手」と「実際にDTLSを張った相手」の同一性を保証します。
指紋検証が守るのは「SDPを送ってきた相手と鍵交換相手が同じか」だけです。シグナリング経路自体が改ざんされ、攻撃者が自分の指紋を差し込めれば、指紋は一致してしまいMITMが成立します。だからシグナリングはTLSで保護し、なりすましを許さないことが安全性の前提になります。Web認証と同様、「経路の暗号化」と「相手の認証」は別問題だと意識してください。
全体の流れ
ここまでを時系列で並べると、WebRTCの接続確立は次のように進みます。
1. RTCPeerConnection 生成、DTLS証明書を準備
2. createOffer → SDP offer をシグナリングで相手へ
3. 双方で ICE候補収集(host → STUNでsrflx → 必要ならTURNでrelay)
4. 候補をTrickle ICEで随時交換しつつ接続性チェック
5. 有効な候補ペアを優先度順に選び経路を確定
6. 選んだ経路上でDTLSハンドシェイク、指紋をSDPと照合
7. 導出鍵でSRTPを開始、メディア/データ送受信
NAT越えという物理的制約を候補の総当たりと中継のフォールバックで吸収し、暗号化を仕様で強制したのがWebRTCの設計です。シグナリングだけを規格外に置くことで、用途に応じた柔軟さと、メディア経路の標準化を両立しています。
まとめ
WebRTCは、相手情報を運ぶシグナリング(規格外)、到達経路を探すICE、経路を守るDTLS/SRTPの3層で成り立ちます。ICEはhost/srflx/relayの候補を集めてペアを総当たりし、STUNで外側アドレスを発見、越えられなければTURNで中継します。暗号化はDTLSの鍵でSRTPを動かし、証明書指紋のSDP照合でMITMを防ぎます。双方向通信の選択肢としては WebSocket と、信頼境界の考え方は 同一オリジンポリシー と併せて読むと、リアルタイム通信の設計判断がつながります。
Web/フロントエンド Article
WebRTCの接続確立(ICE/STUN/TURNとシグナリング)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
WebRTC
比較で見る軸
難易度: advanced / カテゴリ: Web/フロントエンド / タグ数: 6
導入後に効く点
ICEは到達可能なアドレス候補(host/srflx/relay)を集め、両端でペアを総当たりして接続性チェックを行い、最良の1経路を選ぶ。STUNが自分の外側アドレス発見、TURNが中継を担う。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- Web/フロントエンド
- タグ数
- 6
判断チェックリスト
- 自社の用途が「WebRTC / ICE」に近いか確認する。
- 強みである「WebRTCはメディア/データ経路をP2Pで張るが、相手のIP・コーデック・暗号鍵を交換する経路(シグナリング)は規格外で、開発者が別途用意する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。