InnovateAsteriskBrowser-Phone

InnovateAsteriskのブラウザフォン。asterisk browser phone等で検索すると上の方に出てくる。プロジェクトとしては比較的新しいがスタックはSIP.JSを使っている模様。

https://www.innovateasterisk.com/browser-phone/
https://github.com/InnovateAsterisk/Browser-Phone

そもそもクラウド上のAsteriskを使うことが前提になっているのでちと設定が厄介だったのでまとめておく。元の設定手順はオンプレでも『外』から使うことを前提として解説が書かれているので注意。ここではオンプレ/ローカルで使う手順を説明する。

注意:Asteriskはlibsrtp付きでコンパイルしてください。

IA BrowserPhone.png

目次

自己署名の証明書をつくる

そもそもブラウザと通信するにはSSL/TLSが必要となるので証明書が要ります。
今回はローカル(LAN内)で使うことを前提(要はオンプレPBXの内線)にするので証明書を買わずに自己署名でAsteriskサーバのIPアドレス用の証明書をつくり、Chromeにも入れて使います。

以下のページが参考になります(TNX)

https://qiita.com/t-kuni/items/d3d72f429273cf0ee31e
https://github.com/t-kuni/self-sign-cert


SANの書かれたテキストファイルを用意する

以下のような内容でつくります。IPアドレスは自分の環境にあわせてください。例示では192.168.254.234を使います。

subjectAltName = DNS:192.168.254.234, IP:192.168.254.234

san.txtとか適当な名前で保存しておいてください。本来DNSはドメイン名が入るのですがLAN内なのでIPアドレスを書いています。

秘密鍵をつくる

openssl genrsa 2048 > asterisk.key

秘密鍵からCSRをつくる

住所等は適切な値を設定してください。ローカル環境なのであまり気にする必要もありませんが。

# openssl req -new -key asterisk.key  > asterisk.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JA
State or Province Name (full name) [Some-State]:TOKYO
Locality Name (eg, city) []:ITABASHI
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Asterisk
Organizational Unit Name (eg, section) []:PBX
Common Name (e.g. server FQDN or YOUR name) []:192.168.254.238
Email Address []:メールアドレス

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:チャレンジパスワードを指定
An optional company name []:

CSRを署名してサーバ用の証明書をつくる

上の参考にした例にならって10年(3650日)有効にしていますが、まあそんなもんで大丈夫でしょう。

# openssl x509 -days 3650 -req -extfile san.txt -signkey asterisk.key < asterisk.csr > asterisk.crt

Asteriskに証明書を配置する

まず、方針として別な(apacheとか)Webサーバを使うと連携させる設定が面倒になるので、Asterisk組み込みのWebサーバを使います。組み込みのWebサーバを使ってBrowserPhoneだけ提供するように設定していきます。

Asteriskデフォルトでは証明書類は /etc/asterisk/keys に置かれます。デフォルトインストールで勝手証明書類がここに入っている場合には、要らなければ消しておいてください。

mkdir /etc/asterisk/keys
作った証明書類をここに入れます

権限を適切に設定しないと動作しません。Asteriskをasterisk:asteriskで起動している場合には

chown -R asterisk:asterisk /etc/asterisk/keys
chmod 700 /etc/asterisk/keys
chmod 600 /etc/asterisk/keys/*

を実行して権限を設定します。

Asterisk組み込みhttpdを設定する

だいたい以下の通り

[general]
enabled=no
tlsenable=yes
tlsbindaddr=0.0.0.0:5443
tlscertfile=/etc/asterisk/keys/asterisk.crt
tlsprivatekey=/etc/asterisk/keys/asterisk.key
enablestatic=yes
sessionlimit=1000
redirect=/ /static/index.htm

httpは使わないので(httpsのみ)enabled=noにしtlsenable=yesに設定します。asterisk:asteriskで起動している場合、443でlistenできないので適当なポート番号を指定します。

この状態でchromeで接続しようとすると NET::ERR_CERT_AUTHORITY_INVALID のエラーでよくみた警告画面になるはずです。

chromeに証明書をインポートする

今回は自己署名の証明書なので例にならっているのなら asterisk.crt をPCへ転送します。これを信頼できるものとしてchromeにインポートします。
chromeの設定から『プライバシーとセキュリティ』-> 『セキュリティ』と開き『証明書の管理』を開きます。
転送したasterisk.crtを"インポート"で読み込ませ『信頼されたルート証明機関』としてインポートします。
インポートが完了したらchromeを再起動して接続してみてください。中身はともかくhttpsでエラーなしで接続されればOKです。
めんどくさいよね。

なおクラウド上で使うなどの場合にはLet's Encrypt等で正しい証明書を入手して設定していればchrome側でのインポートは要りません。ここではあくまでもオンプレのローカル(LAN)上で使いたいので自己署名の証明書を作って使うことにしています。

Asteriskの設定(httpd以外)

ではAsteriskの設定です。組み込みhttpdは上で説明しています。
だいたいはまあ割と普通です。

rpt.conf

[general]
rtpstart=10000
rtpend=11000
rtcpinterval = 5000

udptl.conf

[general]
udptlstart=4000
udptlend=4999
udptlfecentries = 3
udptlfecspan = 3

PjSIP

PjSIPは設定が多くあるので他の設定は「正常に動く」ようにしておいてください。特にACLは注意。
ここではブラウザフォンにのみ関係する設定を示します。
自分の場合はブラウザフォン用の設定は別ファイルにしpjsip.confからincludeしています。

トランスポート
WebSocket(wss)とTLSのトランスポートを定義します。

[transport-wss]
type = transport
protocol = wss
bind = 0.0.0.0
local_net = 192.168.0.0/16

[transport-tls]
type = transport
protocol = tls
bind = 0.0.0.0
cert_file = /etc/asterisk/keys/asterisk.crt
priv_key_file = /etc/asterisk/keys/asterisk.key
cipher = ADH-AES256-SHA,ADH-AES128-SHA
method = tlsv1
local_net = 192.168.0.0/16


エンドポイントのテンプレート
以下をエンドポイント用のテンプレートとして定義しておきます。

[webphone-endpoint](!)
transport = transport-wss <= TransportにWSSを指定
context = default
rtp_timeout = 120
direct_media = no
dtmf_mode = rfc4733
disallow = all
allow = ulaw,alaw,vp8,vp8,h264 <= CODECは音声のみならulawだけでもOK
use_avpf = yes
media_encryption = dtls
ice_support = yes <=注:sip.jsの関係でICEの設定必要
dtls_verify = fingerprint
dtls_setup = actpass
rtcp_mux = yes
dtls_cert_file = /etc/asterisk/keys/asterisk.crt
dtls_private_key = /etc/asterisk/keys/asterisk.key
dtls_ca_file = /etc/asterisk/keys/asterisk.crt <=自己署名なのでCAはサーバ(asterisk)のものと同じでOK


テンプレートを定義したので各エンドポイント(内線)は以下のような例で書けます。
必要なのはaor,auth,endpoint

[wuser1]
type = aor
max_contacts = 1
qualify_frequency = 60
remove_existing = yes

[wuser1]
type = auth
username = wuser1
password = wpassword1

[wuser1](webphone-endpoint)
type = endpoint
auth = wuser1
aors = wuser1

BrowserPhoneのインストール

これでやっとブラウザフォンが使えるようになります。InnovateAsteriskのBrowserPhoneを入手します。

git clone https://github.com/InnovateAsterisk/Browser-Phone.git

とかでダウンロードします。
このうちPhone/の内容を/var/lib/asterisk/static-httpへコピーします。static-httpに消しては困るものがある場合には事前にバックアップしておいてください。

cd Browser-Phone/Phone
cp -r * /var/lib/asterisk/static-http/.

権限を asterisk:asterisk に変更しておきます。

chown -R asterisk:asterisk /var/lib/asterisk/static-http/

本来はこれだけで使えるようになるのですが、NATありの条件で構成されているため、ローカルで使用しようとするとヘアピンNATがなければ使えませんし、そもそもローカルをわざわざヘアピンするかというのもあるので今回はPjSIPの設定にSTUN等のNAT処理を入れていません。ですが、BrowserPhone自体がNATを使って自分の外側アドレスを持ってくるため、このままでは正常に通信できません。
そこでSTUNを故意に失敗させることでローカルのアドレスで通信させます(作者もこの方法を紹介している)。

/var/lib/asterisk/static-http/phone.js を編集し以下のように「ウソSTUNサーバ」(要は失敗すれば何でもよい)を指定します。
1947行目あたりです。

       sessionDescriptionHandlerFactoryOptions: {
           peerConnectionConfiguration :{
               bundlePolicy: BundlePolicy,
               // certificates: undefined,
               // iceCandidatePoolSize: 10,
               // iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
               iceServers: [{ urls: "stun:stun.l.localhost.localdomain:19302" }], <=これを追加する
               // iceTransportPolicy: "all",
               // peerIdentity: undefined,
               // rtcpMuxPolicy: "require",
           },
           iceGatheringTimeout: IceStunCheckTimeou

ブラウザフォンを使う

LAN上のPCのchromeから https://AsteriskのIPアドレス:5443 にアクセスするだけで使えるようになっているはずです。
Browser Phone06 27 9 07 06.png
画面のようにサーバのアドレスはそのままAsteriskのIPアドレスを、ポートには5443を指定(httpd.confで設定したもの)、WebSocketパースには /ws を指定し、アカウントのところでpjsipのユーザ名とパスワードを指定します。
これで普通に使えると思います。オーディオデバイスの指定等は自分の環境に合わせてよしなにやってください。
exten類は普通に書くだけです。PJSIPのエンドポイントなので特に変わったことをする必要はありません。

メッセージング

テキストメッセージの送受信はSIPベースで、extenで書けます。「呼」としてextenに入ってくるので適切に処理して MessageSend() を使って相手に送るだけです。

https://docs.asterisk.org/Asterisk_20_Documentation/API_Documentation/Dialplan_Applications/MessageSend/
SIPメッセージング

Asterisk 20のサンプル設定ファイルでメッセージングを実装しています