wavekat

SIP over TLS:通話のシグナリングを暗号化

· Eason Guo
#音声AI#SIP#プライバシー

WaveKat Voice は 0.0.56 から SIP over TLS に対応しました。回線の接続方式を TLS に、ポートを 5061 に設定すると、ソフトフォンとプロバイダーの間でやり取りされる SIP シグナリング(REGISTER、INVITE、REFER、BYE)がすべて暗号化された接続を通ります。Mac・Windows・Linux のどれでも使えます。

なぜ TLS が必要なのか

どの通話もシグナリングから始まります。電話機がプロバイダーに登録し、誰に発信するかを伝え、通話を確立します。このやり取りには SIP アカウント、発信先の番号、認証の手続きが含まれています。暗号化されていない UDP では、同じネットワーク経路上にいる誰もがそれを読めます。

これを守る標準的な方法が TLS です。WaveKat Voice とプロバイダーの間の接続は暗号化され、何かを送る前に相手が本当にプロバイダーであることを確認します。業務の電話を担うソフトフォンなら、これくらいはできて当然です。通信を守ることは、私たちが信頼を得るための前提でもあります。そのため、WaveKat Voice ではすべての回線で TLS を使えます。

暗号化される範囲

UDP / TCPTLS
REGISTER の認証のやり取り平文暗号化
発信者、着信者、時刻(INVITE など)平文暗号化
保留、転送、切断平文暗号化
音声(RTP)平文平文
サーバーの身元確認なしあり(証明書で確認)
一般的なポート50605061

見落とされがちなのが認証の行です。SIP は Digest 認証(RFC 3261)を使うので、パスワードそのものがネットワークを流れることはありません。ただし Authorization ヘッダーの response は、パスワードから計算されたハッシュです。UDP なら、同じネットワーク上でそのパケットをキャプチャした人がオフラインで辞書攻撃をかけられ、弱いパスワードはすぐに破られます。TLS なら、キャプチャできるパケット自体がありません。

SIP over TLS の仕組み

通常の SIP は UDP の 5060 番ポートで動くのが一般的で、メッセージはそれぞれ独立したパケットとして、読めるテキストのまま送られます。SIP over TLS が変えるのはその下のトランスポートで、SIP 自体は変わりません。

  1. 接続は 1 本。 ソフトフォンがプロバイダーへ TCP 接続を張ります。ポートは通常 5061 です。
  2. ハンドシェイク。 SIP を送る前に、双方が TLS ハンドシェイクを行います。プロバイダーが証明書を提示し、ソフトフォンはそれが信頼された認証局までたどれること、そしてその SIP ドメイン向けに発行されていることを確認します。そのうえでセッション鍵を取り決めます。
  3. SIP はトンネルの中を通る。 以降の SIP メッセージは、双方向とも同じ接続上を暗号化されて流れます。メッセージ自身もそれを示していて、Via: SIP/2.0/TLS となり、Contact には ;transport=tls が付きます。
  4. 接続は張ったまま。 登録によって接続が維持され、プロバイダーは着信もこの接続を通して送り返します。NAT の内側にある電話機が、ポート転送なしで着信の INVITE を受け取れるのはこのためです。

SIP over TLS のシーケンス図:WaveKat Voice がポート 5061 でプロバイダーへ TCP 接続を張り、TLS ハンドシェイクを終えて SIP ドメインで証明書を検証したあと、REGISTER、401 チャレンジ、認証付き REGISTER、200 OK、着信の INVITE がすべて暗号化された接続上を流れる。

TLS が守るのは 1 区間、つまり WaveKat Voice とプロバイダーの間のリンクです。プロバイダーがその先の通信事業者や電話網へ通話をどう運ぶかは、プロバイダー次第です。

証明書の検証方法

TLS が中間者攻撃を防げるかどうかは、証明書の検証がどれだけ厳格かで決まります。私たちの方針は次のとおりです。

  • システムのルート証明書だけを使う。 証明書は OS の信頼済み CA リストで検証します。独自に同梱した証明書も、例外もありません。
  • サーバーのアドレスではなく SIP ドメインで検証する。 別の送信先サーバーを設定していても、証明書はアカウントの SIP ドメイン向けに発行されている必要があります。これは RFC 5922 の要件です。
  • 失敗したら回線を止める。 平文へのフォールバックも、「接続中」のままの再試行の繰り返しもありません。回線はエラーで止まり、エラーには理由と証明書の SHA-256 フィンガープリントが表示されます。
security certificate not trusted: not signed by a trusted issuer (sha256:5941fb2b…)

TLS の実装には Rust の rustls を使っているので、どのプラットフォームでも OpenSSL には依存しません。

自己署名証明書やプライベート CA には対応しておらず、「この証明書を信頼する」スイッチもありません。プロバイダーがプライベートな証明書を使っている場合、その回線は UDP か TCP のままにしておく必要があります。

切り替える前にプロバイダーの TLS を確認する

アプリの設定を変える前に、標準的な 2 つのコマンドでプロバイダーの TLS が使えるかどうかを確認できます。以下の出力は、2026 年 9 月 26 日にニュージーランドの 2talk と Telnyx の 2 社の SIP プロバイダーに対して実際に実行した結果です。

ステップ 1:TLS のホストとポートを調べる

SIP over TLS 用の SRV レコード(RFC 3263)を公開し、接続先のホストとポートを示しているプロバイダーもあります。Telnyx がそうです。

$ dig +short SRV _sips._tcp.sip.telnyx.com
1 45 5061 sip-anycast1.telnyx.com.
1 95 5061 sip-anycast2.telnyx.com.

各行は優先度、重み、ポート、ホストの順です。優先度は数字が小さいほうが優先され、同じ優先度のレコードは重みに応じて負荷を分け合います。ここでは両方のホストが優先度 1、ポート 5061 なので、クライアントは接続を 2 台に分散し、およそ 3 回に 2 回は sip-anycast2 へつなぎます。

2talk は SRV レコードを公開しておらず、同じ問い合わせをしても何も返りません。これはよくあることなので、その場合はプロバイダーのドキュメントに従ってください。2talk のドキュメントでは lyra.2talk.co.nz、TLS はポート 5061 です。

ステップ 2:厳格なクライアントと同じ方法で証明書を確認する

そのホストに接続し、OpenSSL に SIP ドメインで証明書を検証させます。2talk の場合(出力は一部省略):

$ openssl s_client -connect lyra.2talk.co.nz:5061 \
    -servername lyra.2talk.co.nz -verify_hostname lyra.2talk.co.nz </dev/null
depth=2 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
depth=1 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=RapidSSL TLS RSA CA G1
depth=0 CN=*.2talk.co.nz
Verification: OK
Protocol: TLSv1.3
Verify return code: 0 (ok)

ここから 3 つのことがわかります。証明書は *.2talk.co.nz のワイルドカード証明書で、lyra.2talk.co.nz をカバーしていること。証明書チェーンが DigiCert の公開ルートまでつながっていること。そして接続が TLS 1.3 であること。0 (ok) なら、証明書の検証は通るはずです。

ドメインを間違えるとこうなります。同じサーバーを、証明書がカバーしていない名前で検証した例です。

$ openssl s_client -connect lyra.2talk.co.nz:5061 \
    -servername lyra.2talk.co.nz -verify_hostname sip.example.com </dev/null
Verification error: hostname mismatch
Verify return code: 62 (hostname mismatch)

WaveKat Voice はこの接続を証明書エラーとして拒否します。よく目にするコードは次のとおりです。

結果意味
0 (ok)信頼されており、SIP ドメインに対して有効
62 (hostname mismatch)証明書がこの SIP ドメイン向けに発行されていない。プロバイダーにドメインを確認する
18、19、20自己署名、またはプライベート CA の発行。システムに信頼されていない
接続拒否またはタイムアウトそのホストとポートで TLS が提供されていないか、ファイアウォールがブロックしている

OpenSSL は独自の CA バンドルで検証します。多くの Linux ではそれがシステムの証明書ストアですが、Mac ではそうでないことが多いので、Mac で 20 が出ても結論ではなく目安として扱ってください。

ステップ 3(任意):証明書のフィンガープリントを控える

WaveKat Voice の証明書エラーに表示されるフィンガープリントと照合したい場合は、証明書の SHA-256 フィンガープリントと有効期限を表示します。

$ openssl s_client -connect lyra.2talk.co.nz:5061 -servername lyra.2talk.co.nz </dev/null 2>/dev/null \
    | openssl x509 -noout -fingerprint -sha256 -enddate
sha256 Fingerprint=1D:64:FB:48:21:19:A1:CB:18:43:3B:20:9A:BB:03:96:A1:D2:43:9A:E6:F3:A4:B4:35:3A:33:86:E4:E0:E4:8F
notAfter=Feb 18 23:59:59 2027 GMT

OpenSSL はコロン区切りの大文字で表示し、WaveKat Voice はコロンなしの小文字で表示しますが、16 進数の並びは同じです。プロバイダーが証明書を更新するとフィンガープリントも変わります。これは想定どおりの動きです。

設定方法

  1. プロバイダーのドキュメントで TLS 用のホスト名とポートを確認します。ほとんどは 5061 ですが、TLS 用に別のホスト名を用意しているプロバイダーもあります。たとえばニュージーランドのプロバイダー 2talk のドキュメントには 5061 と書かれています。
  2. 回線を開き、接続方式を TLS にします。ポート欄には 5061 が候補として表示されます。
  3. アカウントの SIP ドメインが、プロバイダーから指定されたものと完全に一致しているか確認します。証明書はこの名前で検証されます。
  4. 保存します。回線は TLS で登録し直されます。

よくある落とし穴があります。接続方式が TCP でポートが 5061 という組み合わせは TLS ではありません。TLS ハンドシェイクを待っているポートへ平文の SIP を送ることになり、登録は失敗します。

回線の設定は WaveKat アカウントに同期されるので、別のコンピューターでサインインしてもその回線は TLS のままです。

本当に TLS で接続されているか確認する

回線の接続情報の下に技術情報へのリンクがあります。このページには、入力した設定値ではなく、動いている接続で実際に使われている値が表示されます。

  • 接続方式が TLS になっている
  • 着信先が ;transport=tls で終わっている
  • SIP メッセージで、すべての Via が SIP/2.0/TLS になっている

Ubuntu 上の WaveKat Voice。回線の技術情報ページで、実際の接続方式が TLS であり、この端末の着信先が transport=tls になっていることを示している。

この回線から送られる REGISTER はおおよそ次のようになります(スクリーンショットと同じデモ回線での例)。

Via: SIP/2.0/TLS 192.0.2.24:5066;branch=z9hG4bK…
Contact: <sip:[email protected]:5066;transport=tls>

確認できない暗号化は、信じるしかない暗号化です。だから TLS 対応と同時に、実際に使われているトランスポートを確認する手段も用意しました。

SIP メッセージのログはメモリ上にだけ保持され、ディスクには書き込まれず、アプリを終了すると消えます。Authorization と Proxy-Authorization ヘッダーの response は記録の時点で消されるので、ログをコピーして誰かに送っても、パスワードのハッシュが漏れることはありません。

トラブルシューティング

症状考えられる原因対処
“Your provider’s server didn’t prove it is who it says it is”(プロバイダーのサーバーが本物であることを証明できませんでした)と表示されるSIP ドメインが証明書と一致しない、またはプロバイダーがプライベートな証明書を使っているSIP ドメインを確認する。プライベートな証明書の場合は、公的に信頼された証明書を使う接続先がないかプロバイダーに問い合わせる
“The secure connection to your provider couldn’t be set up”(プロバイダーとの安全な接続を確立できませんでした)と表示されるポートの誤り(多くは 5060)、またはそのホスト名で TLS が提供されていないプロバイダーのドキュメントにあるポートとホスト名を使う
切り替えたらまったく登録できないTCP + 5061 になっている、またはファイアウォールが送信方向の 5061 をブロックしている接続方式を TLS にする。送信方向の TCP 5061 を許可する
動いていたのに未登録のままになったTLS 接続が切れ(プロバイダーの再起動、ルーターによるアイドル接続の破棄など)、再確立されていない回線でサインインし直すを押す

(この 2 つのエラーメッセージは英語のみで、日本語の画面でも英語のまま表示されます。)

既知の制限:TLS が切れても自動で再接続しない

UDP には切れる接続がないので、ネットワークが一瞬途切れても気づかれません。TLS は長時間張りっぱなしの 1 本の接続なので、プロバイダーが再起動したりルーターが接続を破棄したりすると、サインインし直すを押すまで回線は未登録のままです。無人で着信を受ける回線、たとえば通話フローが夜間に応答する回線がある場合は、切り替える前にこの点を考慮してください。

よくある質問

1 つの回線だけ TLS にできますか?

はい。接続方式は回線ごとの設定なので、回線ごとに UDP、TCP、TLS を個別に選べます。

ポート 5061 を使う必要がありますか?

いいえ。5061 は SIP over TLS の標準ポートですが、プロバイダーのドキュメントに従ってください。別のポートや別のホスト名を使うプロバイダーもあります。

TCP でポート 5061 にすれば TLS と同じですか?

いいえ。それでは TLS のポートへ平文の SIP を送ることになり、登録は失敗します。接続方式を TLS にしてください。

どの TLS バージョンに対応していますか?

TLS 1.2 と TLS 1.3 で、現在安全とされている 2 つのバージョンです。TLS 1.0 と 1.1 はそれぞれ 1999 年と 2006 年のもので、MD5 や SHA-1 といった破られたアルゴリズムに依存しており、2021 年に IETF が正式に非推奨としました(RFC 8996)。主要なブラウザーも何年も前に対応をやめています。これらを外しておくことで、接続が安全でないプロトコルへダウングレードされることを防げます。実際に困ることはほとんどありません。現在の SIP プロバイダーは TLS 1.2 以降に対応しており、上のテストでも 2talk は TLS 1.3 で接続しました。

TLS を使う場合、ルーターのポート転送は必要ですか?

いいえ。着信は、ソフトフォンが自分から張った TLS 接続を通って届きます。ファイアウォールでは、送信方向の TCP 5061(またはプロバイダーが指定するポート)を許可するだけで十分です。

TLS にすると通話が遅くなりますか?

体感できるほどではありません。TLS ハンドシェイクは接続を確立するときに 1 回だけ行われ、その後の登録やすべての通話は、ハンドシェイクをやり直さずに同じ接続を使い回します。

回線が本当に暗号化されているか確認するには?

回線の技術情報を開きます。接続方式が TLS、着信先が ;transport=tls で終わり、SIP メッセージに Via: SIP/2.0/TLS と表示されていれば暗号化されています。

プロバイダーの証明書が期限切れになったり変わったりしたらどうなりますか?

期限切れの証明書は検証に失敗し、回線は証明書エラーで止まります。平文にフォールバックすることはありません。プロバイダーが信頼された CA の別の有効な証明書に切り替えた場合は、何もする必要はありません。WaveKat Voice は特定の証明書に固定するのではなく、証明書チェーンと SIP ドメインを検証しているからです。

自己署名証明書には対応していますか?

いいえ。WaveKat Voice はシステムのルート CA だけを信頼するので、プライベート CA の証明書を使うサーバーには TLS で接続できません。

SIP over TLS と sips: アドレスの違いは何ですか?

sips: アドレスは、通話が経由するすべての区間で TLS を求めます。;transport=tls を付けた sip: アドレスは、いまの区間だけを守ります。WaveKat Voice の回線は後者を使い、あなたとプロバイダーの間の接続を守ります。

試してみる

WaveKat Voice をダウンロードするか 0.0.56 に更新し、回線を TLS に切り替えて、技術情報で確認してみてください。そのほかの接続設定は SIP 設定ガイドにあります。