見出し画像

プロのインフラエンジニアが、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

いいなと思ったら応援しよう!