TURN 機能

Sora は TURN 機能を内蔵しています。

ブラウザの TURN 対応状況

  • Chrome M67 は TURN-UDP / TURN-TCP / TURN-TLS に対応しています
  • Firefox 60 は TURN-UDP / TURN-TCP / TURN-TLS に対応しています
  • Edge 42 は TURN-UDP / TURN-TCP に対応しています
  • Safari 11.1 は TURN-UDP / TURN-TCP に対応しています
    • TURN の IPv6 機能に非対応です

注意

Firefox では TURN の urls を 5 個より多く送るとエラーがコンソールに表示されます。

設定

Sora はデフォルトで TURN 機能が有効になっています

Sora 内蔵の TURN 機能を無効にしたい場合は、 sys.configturn を true から false に変更してください。

sys.config:

%% TURN 機能を有効にするかどうかを指定してください
{turn, true},

%% TURN 機能で利用するレルムを指定してください
{turn_realm, "sora.example.com"},

%% TURN 機能で TURN-TCP を有効にするかどうかを指定してください
%% {turn_tcp, true},

%% TURN 機能で TURN-TCP を有効にした際に利用するポート番号を指定してください
%% {turn_tcp_listen_port, 3478},

%% TURN 機能で TURN-TCP URL 払い出し時のポート番号を指定してください
%% {turn_tcp_port, 3478},

%% TURN 機能で TURN-TLS URL 払い出し機能を有効にするかどうかを指定してください
%% {turn_tls, true},

%% TURN 機能の URL 払い出し機能で利用する FQDN (最後の . なし)を指定してください
%% {turn_fqdn, "sora.example.com"},

%% TURN 機能で TURN-TLS URL 払い出し機能で利用する FQDN (最後の . なし)を指定してください
%% {turn_tls_fqdn, "sora-turns.example.com"},

%% TURN 機能で TURN-TLS URL 払い出し機能を有効にした際に利用するポート番号を指定してください
%% {turn_tls_port, 5349},

設定の優先順位

TURN が有効な場合 Sora が TURN 用の URL を生成する優先順位が存在します。

  1. 認証時に外部サーバから払い出される ipv4_address が採用されます
    • sys.configipv6true の場合は払い出された ipv6_address も採用されます
  2. 外部サーバから ipv4_address が払い出されなかった場合は sys.configipv4_address が採用されます
    • sys.configipv6true の場合は sys.configipv6_address も採用されます
  3. TURN-TLS を有効にしている場合、外部サーバから払い出される turn_tls_fqdn が払い出されなかった場合は sys.configturn_tls_fqdn が採用されます。さらに turn_tls_fqdn が指定されてない場合は turn_fqdn が採用されます。

設定例 1

sys.config:

{ipv4_address, "192.0.2.10"},

{ipv6, false},
{turn, false},

{turn_realm, "sora.example.com"},
{turn_tcp, true},
{turn_tcp_listen_port, 3478},
{turn_tcp_port, 3478},

{turn_tls, true},
{turn_fqdn, "sora.example.com"},
{turn_tls_fqdn, "sora-turns.example.com"},
{turn_tls_port, 5349},

外部サーバから払い出しは turn_tls_fqdn"sora-turns.example.com" の場合、払い出される TURN の urls は 3 つです. UDP のポートは動的に決まるためここでは 54321 としています。

  • turn:192.0.2.10:54321?transport=udp
  • turn:192.0.2.10:3478?transport=tcp
  • turns:sora-turns.example.com:5349?transport=tcp

設定例 2

  • sys.config
    • 全てデフォルト
    • 収集された IP アドレスは 192.0.2.10 と 192.0.2.20
  • 外部サーバから払い出し
    • なし
    • auth_webhook_url コメントアウト

この場合、払い出される TURN の urls は 4 つです。 UDP のポートは動的に決まるためここでは 54321 としています。

  • turn:192.0.2.10:54321?transport=udp
  • turn:192.0.2.10:3478?transport=tcp
  • turn:192.0.2.20:54321?transport=udp
  • turn:192.0.2.20:3478?transport=tcp

内蔵 TURN 機能のメリット

  • Sora との通信経路を強制的に TURN 経由に固定することで、効率よく接続の確立が行えます
    • Type: candidate を待つ必要がなく、Answer さえ受け取ってしまえば接続の確立まで進めます
  • 接続ごとに TURN に使用する Username や Credential を意識する必要がなくなります
  • TURN-TCP や TURN-TLS 機能を使用することで UDP が使用できない環境でも WebRTC を使用することが可能になります

Sora の TURN 機能

  • TURN-UDP での TURN 機能
    • 動的なポートでの TURN-UDP 対応のみに対応しています
  • TURN-TCP での TURN 機能
  • TURN-TLS での TURN URL 払い出し機能
    • Nginx の利用を前提とした機能です
  • ワンタイムな Username や Credential、TURN の URL の自動払い出し
    • Sora がすべて自動で行ってくれます
    • Sora は TURN 機能に必要な Username や Credential をクライアントごとにワンタイムで生成します
  • TURN-UDP / TURN-TCP の IPv6 対応
    • TURN で払い出す urls も IPv6 に対応します
    • TURN-TLS での IPv6 対応については Nginx 依存となっております

Sora の TURN-TCP 機能

デフォルトでは有効になっていますので、無効にしたい場合は sys.config にて {turn_tcp, false} を指定してください。

また、 TURN-TCP で使用するポート番号を指定したい場合は sys.config にて {turn_tcp_port, 3478} のように指定してください。

Sora の TURN-TLS URL 払い出し機能

Sora では TURN-TLS 機能は直接提供していません。 TLS の終端を Nginx を利用するします。つまり Nginx 側で TURN-TLS の TLS を終端して、 TURN-TCP として Sora に投げて貰います。

重要

必ず turn_tcp の設定を有効にしてください

デフォルトでは無効になっていますので、有効にしたい場合は sys.config にて {turn_tls, true} を指定してください。

TURN-TLS で使用するポート番号を指定したい場合は sys.config にて {turn_tls_port, 5349} のように指定してください。デフォルトでは 5349 をお勧めします。

さらに TURN-TLS では使用する場合はかならず証明書の FQDN を指定する必要があります。 sora-turns.example.com の証明書を使用する場合は sys.config にて {turn_tls_fqdn, "sora.example.com"} の用に指定してください。

Nginx の設定

Nginx のバージョンは 1.9 以降が必須です。お勧めは最新版である 1.13 です。

  • stream_backend の server の 192.0.2.0:3478 の IP アドレスは Sora の IP アドレス、ポート番号は Sora sys.configturn_tcp_port のポート番号です
    • IP アドレスにはループバックアドレスは指定しないでください
  • listen 5349 は turn_tls_port に指定したポート番号です
  • ssl_certificate には TURN-TLS に使用する証明書を指定してください
    • ここで指定した証明書のドメインを turn_tls_fqdn に指定してください

設定:

stream {
        upstream stream_backend {
                server 192.0.2.0:3478;
        }
        server {
                listen 5349 ssl;
                proxy_pass stream_backend;

                ssl_certificate      sora-turns.example.com.fullchain.pem;
                ssl_certificate_key  sora-turns.example.com.privkey.pem;

                ssl_protocols TLSv1.2;
                ssl_prefer_server_ciphers on;

                ssl_handshake_timeout 10s;

                ssl_session_cache off;
                ssl_session_tickets off;
        }
}

この設定で動作を確認済です。もし不明点がありましたらサポートまでお問い合わせください。

Sora の TURN IPv6 対応

IPv6 のアドレスが使用可能な場合、クライアントに送られる TURN UDP/TCP サーバ機能も IPv6 にて提供します。

TURN-TCP / TURN-TLS のポートを 80 / 443 に変更する

Nginx の機能をうまく使うことで実現可能です。

詳細は TURN-TCP で 80 番ポート、TURN-TLS で 443 ポートを利用する をご確認ください。

Sora TURN 機能の制限

Sora の TURN 機能には一部制限があります。

  • TURN で使用される UDP のポート番号の固定ができない
    • TURN のポート番号は個々のクライアントに対して動的に生成されるため、固定できません。

この課題を解決したい場合は Sora の TURN 機能を無効にして、別途 TURN サーバを立てる必要があります。

別立てで使用する TURN サーバとして、弊社では coturn サーバをお勧めしています。

coturn/coturn: coturn TURN server project

また、 TURN/STUN サーバを立ててくれるサービスもあります。

TURN 機能を使う場合の注意点

時雨堂がオープンソースで提供している SDK を利用する場合は、ライブラリが対応しているため、対応は不要です

TURN 機能を使用する場合、 Sora はシグナリングの type: offer 時に、WebSocket 経由で送られてくる JSON 形式のメッセージの config: に TURN 接続に必要な情報を含めてクライアントに送信し ます。

この config を PeerConnection を new する際の引数に指定してください。

// ws_url は Sora のシグナリング API の URL を指定する
ws = new WebSocket(ws_url);
// WebSocket 経由で送られてきたメッセージのコールバックを指定する
ws.onmessage = onMessage;

function onMessage(event) {
    var message = JSON.parse(event.data);
    if (message.type == 'offer') {
        // TURN 機能を有効に為た場合は offer メッセージの config に TURN で使用する情報が入っています
        var config = message.config;

        // 途中から省略しています
        RTCPeerConnection.generateCertificate({ name: "ECDSA", namedCurve: "P-256" })
            .then(function(certificate) {
                config.certificates = [certificate];
                // ここで RTCPeerConnection を生成する際の config に送られてきた config を指定してください
                peerConnection = new RTCPeerConnection(config);

この Sora から Offer として送られてくる config には常に接続を TURN 経由で行う仕組みが入っています。

  • urls に記載される URL の IP アドレスは sys.config の ip_address に設定した値になります
  • urls に記載される URL のポート番号は Sora が動的に生成したポートの値になります
  • username と credential は Sora の TURN 機能が動的に生成したワンタイムな値が使用されます
// offer メッセージの config のサンプルです
config = {
    "iceTransportPolicy": "relay",
    "iceTransports": "relay",
    // urls は Sora が動的に生成したポートを使用した URL が入ります
    "iceServers": [{"urls": ["turn:sora.example.com:3478?transport=udp",
                             "turn:sora.example.com:3478?transport=tcp",
                             "turns:sora.example.com:5349?transport=tcp"],
                    "username": "one-time-username",
                    "credential": "one-time-credential"}]
};

外部の TURN を使用する場合

外部の TURN サーバを利用するのは非推奨です、もし利用したい場合はサポートまでご連絡ください

Sora の TURN 機能を使用しない場合は sys.config にて {turn, false} を明示的に指定する必要があります。

sys.config:

{turn, false}

username や credential が固定値の場合

社内使用などで固定値の場合は、何か Sora 側に設定する必要はありません。 クライアント側に TURN サーバの URL や username、 credential を設定してください。

username や credential が動的に生成している場合

既存の認証の仕組みなどがあるのであれば、 そちらから払い出したものをクライアント側に設定していただければ Sora 側に設定する必要はありません。

Sora の認証ウェブフック経由での払い出し

Sora は認証サーバから好きな値をクライアントに送ることができる Metadata 機能をもっています。

この機能を使用することで認証に成功したユーザのみに動的に TURN の username や credential を送ることが可能になります。

Metadata 機能の詳細については metadata の払い出し をご確認ください。

以下は認証成功時に認証サーバで TURN の情報を含んだ返す JSON のサンプルです。

{
    "allowed": true,
    "metadata": {"iceServers": [{"urls": ["turn:192.0.2.10:3478?transport=udp",
                                          "turn:192.0.2.10:3478?transport=tcp",
                                          "turn:[2001:0DB8::10]:3478?transport=udp",
                                          "turn:[2001:0DB8::10]:3478?transport=tcp",
                                          "turns:sora-turns.example.com:5349?transport=tcp"],
                                 "username": "one-time-username",
                                 "credential": "one-time-credential"}]}
}