WebRTC のための TURN サーバ
WebRTCのNAT越えにはSTUN/TURNを利用します。STUNはポートを空けるためにサーバを使い,実際の通信は空けたポートでSTUNサーバを介さずに行います。そのため,パブリックなSTUNサーバが提供されています。一方,ファイヤウォールなどにより,STUNではポートが空けられなかったり空けたポートで通信できないこともあります。このときに使われるのが,TURNというプロトコルなのです。STUNと違い,TURNでは通信がTURNサーバ経由になります。これにより,STUNで外部からの通信を受け付けることができない端末も他の端末と(TURNサーバがプロキシしているのでP2Pと言って良いのかは疑問ですが)P2P通信ができるようになります。ただし,TURNサーバは通信を中継するため,パブリックなサーバがありません。そのため,今回は自分でTURNサーバをインストールして使用します。
TURNサーバのインストール
Ubuntu 18.04 LTS に TURN サーバである coturn
をインストールします。 apt
パッケージにあるので単純に
$ sudo apt install coturn
でインストールできます。
coturn
の設定ファイルの変更前に,まず coturn
のデーモンのオプション設定で以下のように変更することで TURN を有効にします。
/etc/default/coturn
に
TURNSERVER_ENABLED=1
と記述します(デフォルトではコメントアウトされていると思うので,コメントを外します)。
Let's Encrypt による証明書の設定
TURN サーバの設定をする前に,TLS 対応のためにサーバ証明書を準備します。今回は Let's Encrypt を使います。Let's Encrypt の証明書は certbot
を使用して手動でも更新できますが,Web サーバと連携すると自動で更新できるので今回は Apache で自動更新をするために以下のコマンドで証明書を作成します。 turn.example.com
は TURN サーバのドメイン名にしてください。
$ sudo certbot --apache -d turn.example.com
作成した証明書は /etc/letsencrypt/live/turn.example.com/fullchain.pem
に配置されます。また,秘密鍵は /etc/letsencrypt/live/turn.example.com/privkey.pem
に配置されます。
COTURN の設定
Ubuntu 18.04 の apt
でインストールすると coturn
の設定ファイルは /etc/turnserver.conf
に配置されます。すべての設定がコメントアウトされているので,以下のように必要な項目を設定していきます。
# TURN のメッセージに fingerprint を使うための設定で,WebRTC では必須となります。
fingerprint
# Long-term credential 機構を有効にします。こちらも WebRTC では必須です。
lt-cred-mech
# REALM となるドメイン名を指定します
realm=turn.example.com
# STUN/TURN で使用する TLS 証明書と秘密鍵のパスを設定します。
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
# TLS で使う暗号スイートを設定します。
cipher-list="ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS"
# TLS の DH 鍵のビット長を 2066 にします
dh2066
# ログの出力先を設定します
log-file=/var/log/turn.log
# 上述の log-file で指定したファイルにログを書き込みます。これを指定しない場合、プロセス番号等に基づき毎回異なるファイル名でログが作成されます。
simple-log
# TLS1.0, 1.1 を無効にします(TLS1.2, TLS1.3を使用します)
no-tlsv1
no-tlsv1_1
この設定が終わったら以下のコマンドで coturn
サーバを再起動して設定を有効化します。
$ sudo systemctl restart coturn
TURN ユーザの追加と動作確認
coturn
の設定が完了したら https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ の ICE servers に上記の例では stun:turn.example.com:5349
を指定することで STUN の動作確認ができます。
TURN はクレデンシャル(ユーザ名とパスワード)を設定する必要があります。 coturn
は内部にデータベースを持っているので,そちらを使ってテストをするのが最も簡単です。MySQL や Redis など外部のデータベース連携も可能なので,本運用の際はそちらのデータベースを使用することをお勧めします。
内部データベースにクレデンシャルを追加するには turnadmin
コマンドを使います。例えば,ユーザ名 test
,パスワード 2a6f543d28359bd929ce7b141fb12a4360
を以下のコマンドで追加出来ます。
$ sudo turnadmin -a -u test -r turn.example.com -p 2a6f543d28359bd929ce7b141fb12a4360
これを追加したら,先ほどのリンクのサイトに
- STUN or TURN URI:
turn:turn.example.com:5349
- TURN username:
test
- TURN password:
2a6f543d28359bd929ce7b141fb12a4360
を TURN servers に追加することで確認できます。
TURN サーバ側では /var/log/turn.log
を確認することで,認証が成功したかなどを確認できます。
認証に成功した場合は以下のようなメッセージがログに残ります。
50245: session 001000000000000004: new, realm=<turn.example.com>, username=<test>, lifetime=600
50245: session 001000000000000004: realm <turn.example.com> user <test>: incoming packet ALLOCATE processed, success
50245: session 001000000000000004: refreshed, realm=<turn.example.com>, username=<test>, lifetime=0
50245: session 001000000000000004: realm <turn.example.com> user <test>: incoming packet REFRESH processed, success
一方,認証が失敗した場合は,
50341: check_stun_auth: Cannot find credentials of user <test>
50341: session 001000000000000005: realm <turn.example.com> user <test>: incoming packet message processed, error 401: Unauthorized
のようにユーザ test
に対する 401: Unauthorized
エラーが残ります。上記サイトでも ICE candidates に Authentication failed?
というメッセージが残ります。