FreePBX(Asterisk)でTLSを有効化する

ひかり電話を直収したFreePBX(Asterisk)でTLSを有効化するにはどうすれば良いかという話。

前提となる環境

サーバー

RasberryPi 5 8GB
Raspberry Pi OS Lite 12.11
FreePBX 17.0.19.28
Asterisk 22.2.0

クライアント

MicroSIP 3.21.4
Linphone Desktop 5.3.0

証明書の用意

秘密鍵: _.example.com.pem
公開鍵: _.example.com.crt
中間証明書: _.example.com.buldle.crt

がそれぞれ必要。証明書の取得方法は割愛。

今回はLet’s Encryptで取得したワイルドカード証明書(*.example.com)を使う。

FreePBXの設定

[設定]-[Asterisk SIP設定]を開く

[SIP Settings(can_pjsip)]タブを開き、tls- 0.0.0.0を[はい]に
Portを5061(標準そのまま)に

[TLS/SSL/SRTP Settings]項目内の3つのファイルを設定する。

CA Chain File: /etc/asterisk/keys/_.example.com.buldle.crt; 中間証明書
Certificate File: /etc/asterisk/keys/_.example.com.crt; 公開鍵
Private Key File: /etc/asterisk/keys/_.example.com.pem; 秘密鍵

その他オプション

SSL Method: tlsv1_2 ; TLS1.2で接続するように
Verify Client: いいえ ;クライアント、サーバー認証を無効に
Verify Server: いいえ

TLS Versionがデフォルト(tlsv1)のままだと、Linphoneがtlsv1を拒否するため接続出来ない。詳細は不明だが、tlsv1にするとtlsv1_1やtlsv1_2での接続を受け付けない模様。

ファイル自体は事前にWinSCP等で適切なフォルダにアップロードして権限設定も確認しておく必要がある。

中間証明書が読み込まれない問題

Asteriskを再起動したら、opensslで接続してみる

echo | openssl s_client -connect sip.example.com:5061 2> /dev/null

CONNECTED(00000003)

---
Certificate chain
 0 s:CN = *.example.com
   i:C = US, O = Let's Encrypt, CN = R10
   a:PKEY: rsaEncryption, 3072 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jul 12 23:03:01 2025 GMT; NotAfter: Oct 10 23:03:00 2025 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
~~~(省略)~~~
-----END CERTIFICATE-----
subject=CN = *.example.com
issuer=C = US, O = Let's Encrypt, CN = R10
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2066 bytes and written 427 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 3072 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 33D~~~(省略)~~~
    Session-ID-ctx: 
    Master-Key: CAD~~~(省略)~~~
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1756225173
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: yes
---

Verification error: unable to verify the first certificate

と表示されているので、証明書の検証がエラーになっている。

これは証明書自体は登録されているが、中間証明書がなく、上位のルート証明書を検証出来ないために起こる。

AsteriskのCLIを起動して

sudo asterisk -vvvvcr

TLSトランスポートのconfigを確認する

raspi*CLI> pjsip show transport 0.0.0.0-tls

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  0.0.0.0-tls               tls      3     96  0.0.0.0:5061

 ParameterName               : ParameterValue
 ===================================================================
 allow_reload                : false
 allow_wildcard_certs        : No
 async_operations            : 1
 bind                        : 0.0.0.0:5061
 ca_list_file                :
 ca_list_path                :
 cert_file                   : /etc/asterisk/keys/_.example.com.crt
 cipher                      :
 cos                         : 3
 domain                      :
 external_media_address      : 114.x.x.x
 external_signaling_address  : 114.x.x.x
 external_signaling_port     : 0
 local_net                   : 60.x.x.x/255.255.255.252
 local_net                   : 118.x.x.x/255.255.0.0
 local_net                   : 192.168.x.x/255.255.255.0
 method                      : tlsv1_2
 password                    :
 priv_key_file               : /etc/asterisk/keys/_.example.com.key
 protocol                    : tls
 require_client_cert         : No
 symmetric_transport         : false
 tcp_keepalive_enable        : true
 tcp_keepalive_idle_time     : 30
 tcp_keepalive_interval_time : 1
 tcp_keepalive_probe_count   : 5
 tos                         : 96
 verify_client               : No
 verify_server               : No
 websocket_write_timeout     : 100

cert_fileとpriv_key_fileは読み込まれているが、ca_list_fileが読み込まれていない

なお、この状態でもMicroSIPはサーバー証明書の検証をしない(非対応の)ため、TLSで接続出来てしまう。

中間証明書の設定を追加する

FreePBXのConfig Editの方を覗いても、~bundle.crtが指定された形跡もないので、手動で設定を追加する。

[アドミン]-[Asterisk Custom Configuration Files]-[pjsip.transports_custom_post.conf]を開き、以下を入力する。

[0.0.0.0-tls](+)
ca_list_file=/etc/asterisk/keys/_example.com.buldle.crt

Asteriskを再起動してさっきと同じコマンドを入れる

echo | openssl s_client -connect sip.example.com:5061 2> /dev/null

CONNECTED(00000003)
---
Certificate chain
 0 s:CN = *.example.com
   i:C = US, O = Let's Encrypt, CN = R10
   a:PKEY: rsaEncryption, 3072 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jul 12 23:03:01 2025 GMT; NotAfter: Oct 10 23:03:00 2025 GMT
 1 s:C = US, O = Let's Encrypt, CN = R10
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Mar 13 00:00:00 2024 GMT; NotAfter: Mar 12 23:59:59 2027 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
~~~(省略)~~~
-----END CERTIFICATE-----
subject=CN = *.example.com
issuer=C = US, O = Let's Encrypt, CN = R10
---
Acceptable client certificate CA names
C = US, O = Let's Encrypt, CN = R10
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3413 bytes and written 427 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 3072 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: FAA~~~(省略)~~~
    Session-ID-ctx: 
    Master-Key: 382~~~(省略)~~~
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1756225098
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---

今度は中間証明書とルート証明書もちゃんと表示され、Verification: OKになった。

サーバー証明書の検証に対応しているLinphoneでもきちんと接続出来る。

結局何がダメだったのか

/etc/asterisk 内のconfigをダウンロードしてパス名で検索かけてもそれっぽい文字列は一切ヒットしなかったので、「FreePBXのGUIの設定がconfigに反映されていないのでは?」という結論に。

GUI設定は結構便利だけど、壁にぶち当たった時は結局手動でconfigを読んで、該当箇所の項目名で情報を当たる必要があるので、市販のVoIPルーターみたいに全部お任せ設定でやりたいとなると厳しい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です