はじめに
インターネット上でリアルタイムな音声・映像通信やP2Pゲームを実現する際、クライアント同士が直接パケットをやり取りできることが必要です。しかし、企業や家庭の多くのネットワーク環境では、プライベートIPを用いるNAT(Network Address Translation)が導入されており、外部から内部ネットワークの端末に直接到達できない制約があります。
この問題を解決するために用いられる技術がSTUN/TURNになります。
STUN(Session Traversal Utilities for NAT)は、クライアント自身のグローバルIPアドレスと外部ポートを検出し、ICEプロセスで直接通信を試みるための仕組みです。
しかし、対称型NATや厳格なファイアウォール環境下ではSTUNだけでは接続できない場合があります。
この問題を解決するために、TURN(Traversal Using Relays around NAT)を中継サーバーとして介在させることで、どのようなネットワーク環境でも安定した通信経路を確保できます。
本記事では、Akamai Cloud上にcoturnを使ってSTUN/TURNサーバーを構築するメリットを紹介します。
coturnとは
coturnはGitHubでオープンソースとして開発されているSTUN/TURNサーバー実装です。WebRTCやVoIPなどのリアルタイム通信においてクライアント間のNAT越えやファイアウォール越えを高いパフォーマンスで実現できます。
長期認証方式(Long-Term Credential)をはじめ、ICEプロセスとの連携による動的な資格情報管理をサポートしており、TLS/DTLSによる暗号化リレーを標準装備しているため、企業環境やモバイルネットワークでも安全に運用できます。
詳細は公式ドキュメント(Wiki)をご参照ください。
Akamai CloudでSTUN/TURNサーバーを構築するメリット
Akamai Cloudはグローバルに分散したデータセンターとCDNの構築から培ってきたグローバルなネットワークのバックボーンを備えており、UDPベースのSTUN/TURNトラフィックに求められる低レイテンシーと安定したパケット配送を実現できるプラットフォームです。
さらに、Akamai Cloudでは追加のエグレスコストが0.005ドル/GBと業界最安値の水準であり、そもそもインスタンスには一定数の転送量が付与されているため、ほとんどのケースで追加のエグレスコストを支払うことなく、コスト予測が立てやすい点も大きなメリットです。
STUN/TURNのような転送量が多く発生する用途に対して、とても魅力的なコスト構造になっています。
Akamai Cloudでcoturnを構築する
STUN/TURNサーバーのようなネットワーク性能を重視するユースケースの場合、Akamai Cloudのインスタンスはネットワークが最適化されているPremium CPUを利用することを推奨します
今回は、Premium 4GBに対してcoturnをインストールします。
1. パッケージ更新とcoturn/Certbotのインストール
まず、aptでパッケージリストを最新化し、coturn本体とLet’s EncryptのCertbotをインストールします。
sudo apt update
sudo apt install -y coturn certbot
-
coturn
:STUN/TURNサーバー本体 -
certbot
:TLS証明書取得用ツール
2. TLS証明書の取得
HTTP‑01チャレンジ方式でスタンドアロンサーバーを立ち上げ、ドメインを検証して証明書を取得します。
sudo certbot certonly --standalone -d coturn.example.com --agree-tos --no-eff-email -m test@example.com
-
--standalone
:Certbotが一時的にポート80でサーバーを起動 -
-d
:対象ドメイン -
-m
:Let’s Encryptアカウントのメール
取得後の証明書は以下に配置されます:
/etc/letsencrypt/live/coturn.example.com/fullchain.pem
/etc/letsencrypt/live/coturn.example.com/privkey.pem
3. Diffie–Hellmanパラメータの生成
安全なDH鍵交換のため、2048ビットのパラメータを生成します。
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
4. /etc/turnserver.conf
の設定
以下の最小限の設定を turnserver.conf
に追記または編集してください。
###############################
# ネットワーク設定
###############################
listening-port=3478 # STUN/TURN(平文UDP/TCP)
tls-listening-port=5349 # TURN over TLS/DTLS
listening-ip=0.0.0.0 # 全インターフェースでリッスン
external-ip=LINODE_PUBLIC_IP # DNS登録済みのパブリックIP
relay-ip=LINODE_PUBLIC_IP # パケットリレー用IP
###############################
# 認証設定
###############################
lt-cred-mech # Long-Term Credential方式を有効化
realm=coturn.example.com # 認証レルム(ドメイン名)
user=testuser:testpassword # ユーザー認証
###############################
# TLS/DTLS設定
###############################
cert=/etc/letsencrypt/live/coturn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/coturn.example.com/privkey.pem
dh-file=/etc/ssl/certs/dhparam.pem
###############################
# ログ&セキュリティ強化
###############################
fingerprint # メッセージにフィンガープリントを付与
no-multicast-peers # マルチキャストリレーを禁止
verbose # 詳細ログを有効化
log-file=/var/log/turnserver.log # ログファイル出力先
no-rfc5780 # NATビヘイビア検出を無効化
no-stun-backward-compatibility # 古いSTUN後方互換を無効化
allow-loopback-peers # テスト時にループバック接続を許可
5. coturnサービスの起動と自動起動設定
編集が終わったら、systemdで自動起動設定を行い、サービスを再起動します。
sudo systemctl enable coturn
sudo systemctl restart coturn
sudo systemctl status coturn
status
で「active (running)」となっていることを確認してください。
6. STUN到達性テスト
STUNクライアント(stunclient
)を使い、Binding Request が成功するか確認します。
stunclient LINODE_PUBLIC_IP 3478
- Binding test: success が返れば、UDP/3478 で正しくSTUNが動作しています。
-
Mapped address
に表示されるIP/ポートがサーバーのグローバルアドレスです。
7. TURNリレー機能テスト
静的シークレットから動的なユーザー名/パスワードを生成し、turnutils_uclient
でリレー機能を検証します。
turnutils_uclient -u "${USERNAME}" -w "${PASSWORD}" -s -y -g -p "${TURN_SERVER_PORT}" -T "${TURN_SERVER_IP}"
0: (18446744073709551615): INFO: Total connect time is 1 │
│ 0: (18446744073709551615): INFO: 2 connections are completed │
│ 0: (18446744073709551615): INFO: start_mclient: msz=2, tot_send_msgs=0, tot_recv_msgs=0, │
│ tot_send_bytes ~ 0, tot_recv_bytes ~ 0 │
│ 1: (18446744073709551615): INFO: start_mclient: msz=2, tot_send_msgs=0, tot_recv_msgs=0, │
│ tot_send_bytes ~ 0, tot_recv_bytes ~ 0 │
│ 2: (18446744073709551615): INFO: start_mclient: msz=2, tot_send_msgs=0, tot_recv_msgs=0, │
│ tot_send_bytes ~ 0, tot_recv_bytes ~ 0 │
│ 3: (18446744073709551615): INFO: start_mclient: msz=2, tot_send_msgs=5, tot_recv_msgs=5, │
│ tot_send_bytes ~ 500, tot_recv_bytes ~ 500 │
│ 3: (18446744073709551615): INFO: start_mclient: tot_send_msgs=10, tot_recv_msgs=10 │
│ 3: (18446744073709551615): INFO: start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000 │
│ 3: (18446744073709551615): INFO: Total transmit time is 3 │
│ 3: (18446744073709551615): INFO: Total lost packets 0 (0.000000%), total send dropped 0 │
│ (0.000000%) │
│ 3: (18446744073709551615): INFO: Average round trip delay 300.500000 ms; min = 67 ms, max = │
│ 567 ms │
│ 3: (18446744073709551615): INFO: Average jitter 51.000000 ms; min = 20 ms, max = 297 ms
-
-s
:send(データ送信)モード -
-y
:クライアント間エコーテスト -
-g
:DONT_FRAGMENTオプションを付与 -
-T
:TCPリレー(TLS over TCP)
実行結果に「tot_recv_msgs」「Average round trip delay」などが表示されれば、TURNリレーが安定動作している証拠です。
以上で構築は終了です。
ベンチマーク
coturnサーバーのTURNリレー性能を定量的に評価するため、150並列クライアントによるTCP/TLS経由のエコーテストを実施しました。
同一リージョンのPremium 4GBのインスタンスからテストをしています。
実行コマンド
ulimit -n 65535 && turnutils_uclient \
-u testuser \ # 認証ユーザー名
-w testpassword \ # 認証パスワード
-m 150 \ # 同時クライアント数
-n 100 \ # 1クライアントあたり送信メッセージ数
-l 100 \ # 各メッセージサイズ(Bytes)
-p 5349 \ # TURNサーバー TLSポート
-T \ # TCPリレーを使う
-y \ # サーバー内 client-to-client エコーテスト
-g \ # DONT_FRAGMENT オプション付き
Linode Public IP # TURNサーバーのIP
実行結果
0: : Total connect time is 46
0: : Total connect time is 46
0: : 22350 connections are completed
0: : start_mclient: msz=150, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0
1: : start_mclient: msz=150, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0
...
8: : start_mclient: msz=150, tot_send_msgs=14540, tot_recv_msgs=14538, tot_send_bytes ~ 1454000, tot_recv_bytes ~ 1453800
8: : start_mclient: tot_send_msgs=15000, tot_recv_msgs=15000
8: : start_mclient: tot_send_bytes ~ 1500000, tot_recv_bytes ~ 1500000
8: : Total transmit time is 8
8: : Total lost packets 0 (0.000000%), total send dropped 0 (0.000000%)
8: : Average round trip delay 0.042533 ms; min = 0 ms, max = 22 ms
8: : Average jitter 0.657467 ms; min = 0 ms, max = 292 ms
結果として、15,000メッセージを8 秒で処理し、約1,875メッセージ/秒を送信しています。ロスト率0%で、150並列でも安定したリレー性能を確認しました。
平均RTTは0.04 msと極めて低く、Akamai Cloudのネットワークの品質の高さも寄与しています。
まとめ
本記事では、Akamai CloudのPremiumインスタンス上にcoturnを構築することで、世界中のエッジバックボーンを活かした低遅延と高い信頼性を実現できることが分かりました。150並列×100メッセージの負荷試験でもロスト率は低く、平均RTTも低く抑えられていることから、TURNリレー用途でもパフォーマンス面の不安が払拭されるかと思います。
繰り返しになりますが、Akamai Cloud最大の魅力の一つは圧倒的なエグレスコストの安さです。業界最安水準の0.005ドル/GBという低料金設定に加え、インスタンスにはあらかじめ十分な転送量が付帯するため、大量のパケットを扱うSTUN/TURN用途であってもコストを気にせず安心して運用できます。リアルタイム通信サービスを次のレベルに引き上げたい場合は、ぜひAkamai Cloudをご検討ください。
関連記事
アカマイ・テクノロジーズ合同会社の Qiita では、 Akamai Cloud 関連などの開発者向けの記事を掲載しております。