前提条件
- Microsoft Teamsが有効なMicrosoft 365アカウント
- Microsoft 電話システムのライセンスが必要
- example.onmicrosoft.comのようなドメインではなく、独自ドメインを利用している必要あり
- 例:example.com
- Asterisk 18.9.0
- TLS/SRTPが有効になっていること
- Asteriskが動作しているホストのIPアドレスが引けるホスト名があること
- 例:sbc01.example.com(このドメインはMicrosoft 365で利用しているドメインと一致している必要あり)
- SSL証明書(例:sbc01.example.com)
- ダイレクト ルーティングを計画する - SBC 用の公開された信頼できる証明書 - Microsoftに記載されているルート証明機関である必要あり
- 2022/8/20 現在は、Let's Encryptionの証明書のルート証明機関も含まれている(ISRG Root X1)
当然ながら、Microsoftの認定を受けたSBCでは無いため、試すときは自己責任でお願いします。
設定(Microsoft 365側)
- 別の記事にまとめていますので、そちらを参照してください
- Microsoft Teamsでダイレクトルーティングを構成する
事前準備(Asterisk側)
Microsoft 365側からSBC(今回の場合、Asterisk)の死活監視をするためにSIPのOPTIONSメソッドを利用しているのですが、ContactヘッダーにSBCのFQDNが埋め込まれている必要があります。
AsteriskはFQDNを正引きした?、IPアドレスを埋め込むため、そのままでは使えません。
次のようにソースコードを書き換えて、コンパイルします。
※ <SBC FQDN>を書き換えてください。
- Asterisk 20系も同じようにパッチを当てる必要あり
--- work/asterisk-16.10.0/res/res_pjsip_nat.c.orig 2020-05-07 19:14:57.852024000 +0900
+++ work/asterisk-16.10.0/res/res_pjsip_nat.c 2020-05-07 19:15:37.585243000 +0900
@@ -409,7 +409,7 @@
if (!ast_sockaddr_isnull(&transport_state->external_signaling_address)) {
/* Update the contact header with the external address */
if (uri || (uri = nat_get_contact_sip_uri(tdata))) {
- pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport_state->external_signaling_address));
+ pj_strdup2(tdata->pool, &uri->host, "<SBC FQDN>");
if (transport->external_signaling_port) {
uri->port = transport->external_signaling_port;
ast_debug(4, "Re-wrote Contact URI port to %d\n", uri->port);
@@ -418,7 +418,7 @@
/* Update the via header if relevant */
if ((tdata->msg->type == PJSIP_REQUEST_MSG) && (via || (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL)))) {
- pj_strdup2(tdata->pool, &via->sent_by.host, ast_sockaddr_stringify_host(&transport_state->external_signaling_address));
+ pj_strdup2(tdata->pool, &via->sent_by.host, "<SBC FQDN>");
if (transport->external_signaling_port) {
via->sent_by.port = transport->external_signaling_port;
}
設定(Asterisk側)
既存システムと繋ぐ部分は省いてます。
pjsip.conf
[transport-tls]
type=transport
protocol=tls
bind=0.0.0.0:5061
; NAT配下の場合
;external_media_address=xx.xx.xx.xx
;external_signaling_address=xx.xx.xx.xx
cert_file=/usr/local/etc/ssl/o365.crt
priv_key_file=/usr/local/etc/ssl/o365.key
method=tlsv1
[msteams_trunk_out]
type = endpoint
transport = transport-tls
disallow = all
allow = ulaw
aors = aor_msteams_trunk_out
media_encryption = sdes
from_domain = <SBC FQDN>
[aor_msteams_trunk_out]
type = aor
qualify_frequency=60
contact = sip:sip.pstnhub.microsoft.com
[msteams_trunk_in]
type = endpoint
transport=transport-tls
context = default
disallow = all
allow = ulaw, alaw, gsm
media_encryption=sdes
[ident_msteams_trunk_in]
type=identify
endpoint=msteams_trunk_in
match=sip-all.pstnhub.microsoft.com
extensions.conf
[general]
;static=yes
writeprotect=yes
autofallthrough=yes
[default]
; Life Check
exten => msteams_trunk_out,1,HangUp()
; Teams ->
exten => _+81.,1,Dial(IAX2/peer/${EXTEN})
; -> Teams
exten => _9.,1,Set(CALLERID(num)=+81...)
exten => _9.,n,Dial(PJSIP/+81${EXTEN}@msteams_trunk_out)
パケットフィルタ
Asteriskは割と攻撃されやすい気がするので、SIPのシグナリングパケットを制限します。
MicrosoftのドキュメントにFQDNやアドレスレンジは記載されているので、これを参考にするだけです。
FreeBSDのpfだとこんな感じ。アドレスレンジは2021/6/30現在
/etc/pf.conf
ext_if="vtnet0"
pass in quick on $ext_if proto tcp from 52.112.0.0/14 to ($ext_if) port SIGNALPORT
pass in quick on $ext_if proto tcp from 52.120.0.0/14 to ($ext_if) port SIGNALPORT
block in quick on $ext_if proto tcp from any to ($ext_if) port SIGNALPORT
参考にしたサイト
-
Proof of Concept: Connecting Microsoft Teams via Direct Routing with an Asterisk PBX - ayonik.de
- ほぼこのサイトの受け売りです。
-
Microsoft Teams, Direct Routing and Asterisk running on a Raspberry Pi 4. - FULLY'S BLOG
- 本記事と同じことをRPi4でやってる人
-
OpenSIPS as MS Teams SBC
- OpenSIPSだと、Asteriskみたいにコンパイルし直さなくても、Contactヘッダーに任意のFQDN埋め込めるみたいだけど、Asteriskユーザからすると、設定が難解すぎて諦めました。
- 別記事でopenSIPSとTeams繋げました
- Microsoft TeamsとopenSIPSを接続する