プロのインフラエンジニアが、ubuntu で、Asteriskを設定してみた。
君、独り身だよね?というツッコミが聞こえてきそう。。
と、言うわけで。一人なのにIP-PBXです。無駄に内線通話とか出来ます。今はスマホ内線のみですが、IP多機能とか欲しくなってきてる今日このごろ。ウィスパーとかできるのかな?使用するIP-PBXはasteriskと言って、簡単に言えばLinuxに入れる、オープンソースなソフトウェア型のIP-PBXです。だもんで、IP端末しか繋がりません、多分。VoIPゲートウェイとか使えば出来るのですが、、、どうでしょう。なんか、物理アプライアンスではアナログのポート持ちのものもあるようなのですが、正直、そんなん買って苦労するなら、大人しくビジネスホン買いなよ。楽よ。アスタ使える人が居なくなったり、へそ曲げちゃったら大変よ。。
とりあえず、バカな人柱がイロイロ苦労していきます。私んちは非常に変な環境になっているので、それならではの苦労があります。いや、SIPとRTPについてよ~くわかったよ。。。なんとなくNATを越えられないサービスの理由がわかったよ。
途中で、設定を継ぎ足ししていきますが、最後に最終型の設定を再掲しますので、安心してください。
★準備
ではひとまず、いろいろパッケージを最新化しておいて。
sudo apt update
sudo apt upgrade
再起動して、準備OK!
sudo shutdown -r now
★Asteriskインストール
ココでアレ?っと思う人も多いかもしれません。だって、ちまたでは、どっかからwgetして~から始まるのですが、ubuntuでaptしてみると入ります。2022年8月17日現在だと、Ubuntu 22.04.1 LTSから、aptして入るのは、Asterisk 18.10.0が入ります。超最新というわけではないのですが、比較的新しっぽいので良しとします。
asteriskパッケージの検索して確認。
sudo apt search asterisk
sudo apt show asterisk
インストール実行。
sudo apt install asterisk -y
Asteriskを、自動起動設定し、起動します。
systemctl enable asterisk
systemctl start asterisk
起動を確認します。Active: active (running)となっていればOK!
sudo systemctl status asterisk
え?って言うほど簡単。もう、物理も仮想もアプライアンスなんていらんよ。。。。
★Asteriskの設定 ~ とりま、内線で通話したい!編 ~
では、設定していきましょう。コレも古めのページではsip.confをいじるみたいなのですが、Asterisk 16からはデフォルトでpjsip.confの様なので、こちらで設定してきます。切り替えのときには多分、大混乱が生じたんだろうなぁ。リプレースのときとか、設定が流用出来ないなんて、なんて地獄。。。特に、アスタが使える人が異動してたら、、、と、思うとゾッとしますよね。
デフォルトの設定は、正直必要ないので、リネームして作り直します。
mv /etc/asterisk/pjsip.conf /etc/asterisk/pjsip.conf.org
vi /etc/asterisk/pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
[6001]
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=ulaw
auth=6001
aors=6001
[6001]
type=auth
auth_type=userpass
password=6001
username=6001
[6001]
type=aor
max_contacts=1
[6002]
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=ulaw
auth=6002
aors=6002
[6002]
type=auth
auth_type=userpass
password=6002
username=6002
[6002]
type=aor
max_contacts=10
変更した設定を反映させるためにAsteriskを再起動して、起動を確認します。Active: active (running)となっていればOK!
sudo systemctl restart asterisk
sudo systemctl status asterisk
スマホにIPアプリ電話をインストールして、確認!私は、AndroidではMizuDroid、iPhoneではAGEphoneを使っています。まぁ、使えれば何でも良いです。レジストするのだって、AsteriskのサーバIPとID/PWだけで出来ます。
が!しかし子機はコレでレジストできますが、通話はまだできません、、、流石はPBX。そこまで設定がいるのかよ!って思います。そうね、レジストと、呼をどこに落とすかって、設定は別だよね。でもまぁ。マジモンのビジホンよりはマシ。
これも、デフォルトの設定は正直必要ないので、リネームして作り直します。
mv /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.org
vi /etc/asterisk/extensions.conf
[general]
static=yes
writeprotect=no
[from-internal]
exten = 100,1,Answer()
same = n,Wait(1)
same = n,Playback(hello-world)
same = n,Hangup()
[6001]
exten = 6001,1,Dial(PJSIP/6001,30,r)
same = n.Hangup()
[6002]
exten = 6002,1,Dial(PJSIP/6002,30,r)
same = n.Hangup()
まぁ、簡単には6001が呼ばれたら、6001の子機に呼を落とす。6002が呼ばれたら、6002に呼を落とす。だけなんですが。まぁ、100の設定は遊びです。
変更した設定を反映させるためにAsteriskを再起動して、起動を確認します。Active: active (running)となっていればOK!
sudo systemctl restart asterisk
sudo systemctl status asterisk
ここで、AsteriskのCLIを起動して遊んでみます。
asterisk -rvvvvv
これで、AsteriskのCLIを起動しておいて、
6002の子機をレジストすると。
-- Added contact 'sip:6002@192.168.200.9:15060;ob' to AOR '6002' with expiration of 600 seconds
== Endpoint 6002 is now Reachable
6002の子機のレジストを解除すると(アプリや設定で方法は変わる。)
-- Removed contact 'sip:6002@192.168.200.9:15060;ob' from AOR '6002' due to request
== Contact 6002/sip:6002@192.168.200.9:15060;ob has been deleted
== Endpoint 6002 is now Unreachable
と、出るので子機の登録がリアルタイムにわかります。6002の子機のIPは192.168.200.9ですが、これはDHCPで払い出してるのでなんでも良いはずです。また、
pjsip show endpoints
とか、入れると、その時の、レジストした子機の番号とIPアドレスのくくりつけなんかが分かります。
CLIから離脱するには quit です。これで、6001の子機から6002へダイヤルすると、6002の子機が鳴って、取ると会話ができます。IP電話の遅延とやらが理解できます。ココまでで、内線には使えますが、、、これじゃあ面白くないですよね!
★Asteriskの設定 ~ やっぱ、ひかり電話で発呼したい編 ~
まずは、ひかり電話の内線としてレジストできるように、ホームゲートウェイ(HGW)の設定をします。HGWにログオンして、電話設定→内線設定から設定します。
MACアドレスを登録ですが、私の環境では、NATをしている関係でHGWから見えるL3デバイスはルータですので、ルータのWAN側の口のMACアドレスを登録します。HGW直下にAsteriskサーバがある場合は、AsteriskサーバのNICのMACアドレスを登録します。また、MACアドレスを登録した内線番号とそれに付随する、ユーザIDとパスワードをメモしておきます。また、ここではHGWをのLAN側のIPを192.168.1.1、設定した内線番号を3とします。
まずは、レジストしないと話が始まらないので、pjsip.confをイジります。とりあえず、下記をpjsip.confの続きに追記してください。
vi /etc/asterisk/pjsip.conf
[hikari-denwa]
type=registration
transport=transport-udp
outbound_auth=hikari-trunk
server_uri=sip:192.168.1.1 ;HGWのLAN側のIPアドレス
client_uri=sip:3@192.168.1.1 ;(内線番号)@HGWのLAN側のIPアドレス
retry_interval=60
[hikari-trunk]
type=auth
auth_type=userpass
password=(HGWで表示されるPW) ;(内線番号)の(ユーザID)のパスワード。流石に隠します。
username=0003 ;(内線番号)の(ユーザID)ここでは0003
[hikari-trunk]
type=aor
contact=sip:192.168.1.1 ;HGWのLAN側のIPアドレス
[hikari-trunk]
type=endpoint
transport=transport-udp
context=from-hikari
disallow=all
allow=ulaw
outbound_auth=hikari-trunk
aors=hikari-trunk
direct_media=no
from_user=3 ;HGWの(内線番号)
from_domain=192.168.1.1 ;HGWのLAN側のIPアドレス
dtmf_mode=inband
[hikari-trunk]
type=identify
endpoint=hikari-trunk
match=192.168.1.1 ;HGWのLAN側のIPアドレス
また、呼制御を行う必要がありますので、extensions.confをイジります。とりあえず、下記をextensions.confの続きに追記してください。
vi /etc/asterisk/extensions.conf
exten => _0.,1,Set(CALLERID(num)=${MYNUMBER})
exten => _0.,n,Set(CALLERID(name)=${MYNUMBER})
exten => _0.,n,Dial(PJSIP/${EXTEN}@hikari-trunk)
[from-hikari]
exten => s,1,Dial(PJSIP/6002,30,r)
変更した設定を反映させるためにAsteriskを再起動して、起動を確認します。Active: active (running)となっていればOK!
sudo systemctl restart asterisk
sudo systemctl status asterisk
これで、人によってはひかり電話で発着信できます。、また、
exten => s,1,Dial(PJSIP/6002,30,r)
の、PJSIP/6002の部分の子機に呼がおちていきますので、PJSIP/6001&PJSIP/6002のように書けば、ひかり電話の着信を落とす子機を増やせます。
ここで、人によっては と、書きました。そう私の環境ではコレでは動きません。HGWみるとレジストできてるっぽいし、asteriskのCLIでも
これで、AsteriskのCLIを起動しておいて、
asterisk -rvvvvv
レジストを確認すると、
pjsip show registrations
<Registration/ServerURI..............................> <Auth..........> <Status.......>
hikari-denwa/sip:192.168.1.1 hikari-trunk Registered
Objects found: 1
と、表示されるんで、ひかり電話にはレジストできてるんですよ。でも、この状態で外線から、ひかり電話の局番に電話してもずっとリングバックトーンが流れるばかりで、内線子機側にはなにも表示されません。ちな、AsteriskのCLIにも何も表示されません。これ、パケットをキャプチャすると分かるんですが、このままだと。AsteriskのサーバのIPアドレスで登録されます。私の環境では、ルータがNATをしているため、AsteriskのサーバIPにHGWから通信を開始できないのです。だって、ルータのLAN側のIPアドレスなんてHGWしらないもん。と、言うわけで少し工夫をします。
NATを動的に行うのではなく、Asteriskサーバに関しては静的にマップする。
です。はい。そうすると、IPのレベルではHGWのLAN側のアドレスにAsteriskのサーバが見えるようになるため、動く・・・動かない。そう、これだけだと、IPヘッダは静的NATされてるんですが、データペイロードの中にあるレジストしたいIPが、元のAsteriskサーバのIPなので、HGWが通信を開始できないのは自明なのです。と、言うことはレジストするときから、データペイロードの中も偽装してしまえば良いのです。
いやぁ、こういう設定もできるんですねぇと、言うことでとりあえず、下記をpjsip.confの続きに追記してください。あ、ここで192.168.1.193っていうのが、ルータでNATした先のHGWのLAN側セグメントのアドレスで、192.168.200.0/24がAsteriskサーバが所属してるセグメントのアドレスです。下の追記を[transport-udp]のコンテクストの中に記載します。
vi /etc/asterisk/pjsip.conf
external_media_address=192.168.1.193
external_signaling_address=192.168.1.193
local_net=192.168.200.0/24
local_net=127.0.0.1/32
要は、下記の位置に書き込んでください。
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
external_media_address=192.168.1.193
external_signaling_address=192.168.1.193
local_net=192.168.200.0/24
local_net=127.0.0.1/32
変更した設定を反映させるためにAsteriskを再起動して、起動を確認します。Active: active (running)となっていればOK!
sudo systemctl restart asterisk
sudo systemctl status asterisk
これで、私の環境では、発着信OKです。会話もきちんとできます。もうツギハギだらけですが、動けば正義です。実は、発着信は出来るけど、会話はできない(音が出ない)パターンもあったのですが、なんか再現できなくなっちゃったので、割愛です。
ちなみに、extensions.confのなかの、
[from-hikari]
exten => s,1,Dial(PJSIP/6002,30,r)
を
#[from-hikari]
#exten => s,1,Dial(PJSIP/6002,30,r)
って、コメントアウトしておくと、子機に呼が降りてきません。静かです。私はこの環境で運用しています。なぜかって?それは、、、
家電なんて出る気がない。
からです。じゃあ、なんでひかり電話なんて維持してるんだよ!って、話ですが。いくつか理由があります。それはまた別のお話。
では、最後に設定を再掲して。さよーならー。
そうそう、設定変更したら必ず、sudo systemctl restart asterisk.service をお忘れなく。。。
夜中に電話がなります。
★<今回設定した設定のまとめ>
(ただし、内線のPWは伏せておきます、また説明にはないですが6003の子機も運用してるため、設定があります)
・pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
external_media_address=192.168.1.193
external_signaling_address=192.168.1.193
local_net=192.168.200.0/24
local_net=127.0.0.1/32
[6001]
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=ulaw
auth=6001
aors=6001
[6001]
type=auth
auth_type=userpass
password=6001
username=6001
[6001]
type=aor
max_contacts=1
[6002]
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=ulaw
auth=6002
aors=6002
[6002]
type=auth
auth_type=userpass
password=6002
username=6002
[6002]
type=aor
max_contacts=10
[6003]
type=endpoint
transport=transport-udp
context=from-internal
disallow=all
allow=ulaw
auth=6003
aors=6003
[6003]
type=auth
auth_type=userpass
password=6003
username=6003
[6003]
type=aor
max_contacts=10
[hikari-denwa]
type=registration
transport=transport-udp
outbound_auth=hikari-trunk
server_uri=sip:192.168.1.1
client_uri=sip:3@192.168.1.1
retry_interval=60
[hikari-trunk]
type=auth
auth_type=userpass
password=--------- ;内線のPWは伏せます。
username=0003
[hikari-trunk]
type=aor
contact=sip:192.168.1.1
[hikari-trunk]
type=endpoint
transport=transport-udp
context=from-hikari
disallow=all
allow=ulaw
outbound_auth=hikari-trunk
aors=hikari-trunk
direct_media=no
from_user=3
from_domain=192.168.1.1
dtmf_mode=inband
[hikari-trunk]
type=identify
endpoint=hikari-trunk
match=192.168.1.1
・extensions.conf
[general]
static=yes
writeprotect=no
[hikari-denwa]
type=registration
transport=transport-udp
outbound_auth=hikari-trunk
server_uri=sip:192.168.1.1
client_uri=sip:3@192.168.1.1
retry_interval=60
[hikari-trunk]
type=auth
auth_type=userpass
password=--------- ;内線のPWは伏せます。
username=0003
[hikari-trunk]
type=aor
contact=sip:192.168.1.1
[hikari-trunk]
type=endpoint
transport=transport-udp
context=from-hikari
disallow=all
allow=ulaw
outbound_auth=hikari-trunk
aors=hikari-trunk
direct_media=no
from_user=3[from-internal]
exten = 100,1,Answer()
same = n,Wait(1)
same = n,Playback(hello-world)
same = n,Hangup()
[6001]
exten = 6001,1,Dial(PJSIP/6001,30,r)
same = n.Hangup()
[6002]
exten = 6002,1,Dial(PJSIP/6002,30,r)
same = n.Hangup()
[6003]
exten = 6003,1,Dial(PJSIP/6003,30,r)
same = n.Hangup()
#Hikari-Denwa Dial-out Sample(PJSIP)
exten => _0.,1,Set(CALLERID(num)=${MYNUMBER})
exten => _0.,n,Set(CALLERID(name)=${MYNUMBER})
exten => _0.,n,Dial(PJSIP/${EXTEN}@hikari-trunk)
[from-hikari]
exten => s,1,Dial(PJSIP/6002&PJSIP/6003,30,r)
from_domain=192.168.1.1
dtmf_mode=inband
[hikari-trunk]
type=identify
endpoint=hikari-trunk
match=192.168.1.1