Asterisk18 + Ubuntu で内線電話網を構築

# 初めに
このメモは [xecusさん](https://qiita.com/xecus) が発行されている [記事の内容](https://qiita.com/xecus/items/3f816e9fa0b31e9f3c2b) を再現して、一部詰まったところを記録したものです。  

Asteriskで過去に内線環境自体は構築したことがあるのですが、そのときは声が届かず検証の時間も準備していなかったため、断念しました。今回はサクッとできる記事を見つけ、やってみたら本当にできたけど。っていう内容です。←備忘録です。

# 環境
[ConoHa](https://www.conoha.jp/conoha/) VPS上に Ubuntu インスタンスを立ち上げ、その中に Asteriskを立てています。  
- VPS/RAM 1GB/CPU 2Core
- OS/Ubuntu 20.04 LTS
- [asterisk/18.3.0](https://www.asterisk.org/downloads/)

参考にしたもの:[Asterisk17 + Ubuntuでさくっと内線電話網を構築する](https://qiita.com/xecus/items/3f816e9fa0b31e9f3c2b)

# Asterisk18 のビルド
ソースコードから落としてビルドします。

```bash
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-18.3.0.tar.gz
tar xf asterisk-*
cd asterisk-*/
./contrib/scripts/install_prereq install
./configure --with-jansson-bundled
sudo make -j4
sudo make install
sudo make samples # 初期の設定ファイル等がインストールされる
```

# Asterisk18 の設定
内線電話番号6001,6002を構築し、お互いにつながるようにします。  
設定ファイルは基本的に最下部に追記しました。  

## pjsip.conf の設定
SIPサーバーに関する設定や内線電話（SIPクライアント）からの認証情報を設定します。

```text:/etc/asterisk/pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0

[6001]
type=endpoint
context=from-internal
disallow=all
allow=ulaw
auth=6001
aors=6001
rewrite_contact = yes # 6001がNAT環境下の場合、必要。

[6001]
type=auth
auth_type=userpass
password=unsecurepassword
username=6001

[6001]
type=aor
max_contacts=10

[6002]
type=endpoint
context=from-internal
disallow=all
allow=ulaw
auth=6002
aors=6002
rewrite_contact = yes # 6002がNAT環境下の場合、必要。

[6002]
type=auth
auth_type=userpass
password=unsecurepassword
username=6002

[6002]
type=aor
max_contacts=10
```

## extensions.conf の設定
内線電話（SIPクライアント）からの発着信時のルールをここに記述します。

```text:/etc/asterisk/extensions.conf
[from-internal]

exten = 100,1,Answer()
same = n,Wait(1)
same = n,Playback(hello-world)
same = n,Hangup()

# 6001がコールされたらSIPの6001を呼び出す
exten = 6001,1,Dial(PJSIP/6001,30,r)
same = n.Hangup()

# 6001がコールされたらSIPの6001を呼び出す

exten = 6002,1,Dial(PJSIP/6002,30,r)
same = n.Hangup()
```

# UFWの設定 
外国からの攻撃がすごいので、UFWによるファイアウォールを入れます。
日本のIPアドレスは [JPNIC](https://www.nic.ad.jp/ja/ip/list.html) 参照していい感じに設定

```bash
sudo apt install ufw
sudo ufw enable
sudo ufw default DENY
# SIP用ポートを許可
sudo ufw allow from XXX.XXX.XXX.XXX/32 to any port 5060 proto udp
# RTP用ポートを許可
sudo ufw allow from XXX.XXX.XXX.XXX/32 to any port 10000:20000 proto udp
sudo ufw reload
```

# Asterisk18 のサービス化
このままでは普通のサービスのように `sudo systemctl restart asterisk` ができないのでサービス化します。

新規作成: /etc/systemd/system/asterisk.service 

refs: [Asterisk Startup systemd](https://www.voip-info.jp/index.php/Asterisk_Startup_systemd)

```bash:
sudo useradd asterisk -s /sbin/nologin
```

```text:/etc/systemd/system/asterisk.service
[Unit]
Description=Asterisk PBX and telephony daemon
Documentation=man:asterisk(8)
Wants=network.target
After=network.target

[Service]
Type=simple
User=asterisk
Group=asterisk
Environment=HOME=/var/lib/asterisk
WorkingDirectory=/var/lib/asterisk
ExecStart=/usr/sbin/asterisk -f -C /etc/asterisk/asterisk.conf
ExecStop=/usr/sbin/asterisk -rx 'core stop now'
ExecReload=/usr/bin/asterisk -rx 'core reload'

# safe_asterisk emulation
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

```bash:
sudo systemctl daemon-reload
sudo systemctl enable asterisk
sudo systemctl unmask asterisk
```

# Asterisk18 のサービス起動

```bash
sudo systemctl start asterisk
sudo systemctl status asterisk
```

# Asterisk18 の起動確認

```bash
systemctl status asterisk
ss -ltu | grep sip
```

```bash:sample_output
ubuntu@xxx.xxx.xxx.xxx:~$ systemctl status asterisk
● asterisk.service - Asterisk PBX and telephony daemon
     Loaded: loaded (/etc/systemd/system/asterisk.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-04-27 23:20:59 JST; 5min ago
       Docs: man:asterisk(8)
   Main PID: 92141 (asterisk)
      Tasks: 66 (limit: 1067)
     Memory: 67.7M
     CGroup: /system.slice/asterisk.service
             mq92141 /usr/sbin/asterisk -f -C /etc/asterisk/asterisk.conf
ubuntu@xxx.xxx.xxx.xxx:~$ ss -ltu | grep "sip\|iax"
udp    UNCONN  0        0                                0.0.0.0:sip                                    0.0.0.0:*                                      
udp    UNCONN  0        0                                0.0.0.0:iax                                    0.0.0.0:*
ubuntu@xxx.xxx.xxx.xxx:~$
```

# 実機テスト
検証で使用したApp: 
iOS: https://apps.apple.com/jp/app/sessiontalk-sip-softphone/id362501443
Android: https://play.google.com/store/apps/details?id=co.froute.session_chat&hl=ja&gl=US

## 設定項目
アカウント名: テキトー
ユーザネーム: 6001 or 6002 or 作ったやつ
パスワード: 上の設定そのままなら `unsecurepassword`
ドメイン: サーバのIPアドレス or FQDN
認証ユーザネーム: ユーザネームと同じ

## ios
![IMG_7286.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104374/839dc38c-a748-ee1e-b46f-b53912296a16.png)

## android
![Screenshot_2021-04-27-23-32-45-856_co.froute.session_chat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104374/7feed8c3-14d5-d8ca-5aa4-ffd2c79c0e51.jpeg)

# 最後に
元のドキュメントに、サービス化の設定書いてないのに `systemctl` 書いてたり、`sudo`してなかったりでいろいろ苦労したけど、調べたらすぐ出てきたからそんなにドハマリはしなかった。一応コピペでできるように作ってるけど、うまく行かない箇所あれば答えられる範囲で答えます。保留音の設定とかはしらん。あと、うまく行かない人は一度エラーメッセージでぐぐってみると答え載ってる。( ｰ`дｰ´)ｷﾘｯ