asteriskでIP内線電話を構築する。電話機はスマホ＋アプリ

IP内線電話をインターネット上のVPS上に構築する。

- asterisk-13.32.0をソースからビルド
- 設定のGUI(free-pbx)は使わない

![IP内線電話onVPS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384104/f5803957-1535-41a8-ffef-5bf0582ba005.png)

# install
インストール作業は、rootユーザで、 ```/usr/local/src``` 配下のディレクトリで作業する。


## 前提ソフトのインストール
以下のサイトの通り。多謝、多謝
[参考サイト１](https://zzaj.net/?p=1156)
[参考サイト２](https://zzaj.net/?p=1171)

### Development tools
```bash:
# yum groupinstall "Development Libraries" "additional Development"
# yum install gcc gcc-c++
# yum install libxml2 libxml2-devel openssl-devel ncurses-devel sqlite-devel newt-devel libuuid-devel uuid-devel
# yum install json-c json-c-devel
# yum install subversion
```

### jansson
```bash:
# wget http://www.digip.org/jansson/releases/jansson-2.7.tar.gz
# tar xzvf jansson-2.7.tar.gz
# cd jansson-2.7
# ./configure
# make && make install
```

### pjsip 
```bash:
# wget http://www.pjsip.org/release/2.4/pjproject-2.4.tar.bz2
# tar xvjf pjproject-2.4.tar.bz2
# ./configure --prefix=/usr/local --libdir=/usr/lib64 --enable-shared --disable-sound --disable-resample --disable-video --disable-opencore-amr CFLAGS='-O2 -DNDEBUG'
# make dep && make && make install
# ldconfig
# ldconfig | grep pj
```

### asterisk
スマホアプリがsip利用なので、make menuselectで、```chan_sip```を利用。

```bash:
# wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz
# cd asterisk-13.*.*
# ./bootstrap.sh
# ./configure --libdir=/usr/lib64
# make menuselect
# make && make install && make samples
```
## インストール後の設定
### systemd
```conf:
# cat /usr/lib/systemd/system/asterisk.service
----
# asterisk.service
#  oss PBX
#
[Unit]
Description=Asterisk PBX and Telephony Daemon
After=network-online.target
 
[Service]
Type=simple
Environment=HOME=/var/lib/asterisk
WorkingDirectory=/var/lib/asterisk
User=asterisk
Group=asterisk
ExecStart=/usr/sbin/asterisk -f -C /etc/asterisk/asterisk.conf
ExecStop=/usr/sbin/asterisk -rx 'core stop now'
ExecReload=/usr/sbin/asterisk -rx 'core reload'
PrivateTmp=true
  
[Install]
WantedBy=multi-user.target
----
```

### permissionの設定
```bash:
# adduser -u 5000 asterisk -s /sbin/nologin -d /var/lib/asterisk
# chown -R asterisk:asterisk /var/lib/asterisk
# chown -R asterisk:asterisk /var/log/asterisk
# chown -R asterisk:asterisk /var/run/asterisk
# chown -R asterisk:asterisk /var/spool/asterisk
# chmod -R u=rwX,g=rX,o= /var/lib/asterisk
# chmod -R u=rwX,g=rX,o= /var/log/asterisk
# chmod -R u=rwX,g=rX,o= /var/run/asterisk
# chmod -R u=rwX,g=rX,o= /var/spool/asterisk
```

### selinux対応
```bash:
# cd /var/lib
# ls -Z | grep asterisk
drwxr-x---. asterisk       asterisk       system_u:object_r:var_lib_t:s0   asterisk
# chcon -R system_u:object_r:asterisk_var_lib_t:s0 asterisk
# ls -Z | grep asterisk
drwxr-x---. asterisk asterisk system_u:object_r:asterisk_var_lib_t:s0 asterisk
 
# cd /var/run
# ls -Z | grep asterisk
drwxr-x---. asterisk       asterisk       system_u:object_r:var_run_t:s0   asterisk
# chcon -R system_u:object_r:asterisk_var_run_t:s0 asterisk
# ls -Z | grep asterisk
drwxr-x---. asterisk       asterisk       system_u:object_r:asterisk_var_run_t:s0 asterisk
 
# cd /var/spool
# ls -Z | grep asterisk
drwxr-x---. asterisk asterisk system_u:object_r:var_spool_t:s0 asterisk
# chcon -R system_u:object_r:asterisk_spool_t:s0 asterisk
# ls -Z | grep asterisk
drwxr-x---. asterisk asterisk system_u:object_r:asterisk_spool_t:s0 asterisk
```

```bash:
# semanage fcontext -a -t asterisk_var_lib_t "/var/lib/asterisk/(/.*)?"
# semanage fcontext -a -t asterisk_var_run_t "/var/run/asterisk/(/.*)?"
# semanage fcontext -a -t asterisk_spool_t "/var/spool/asterisk/(/.*)?"
```
### selinux対応その２
/var/log/audit/audit.logを見ながら、エラーがなくなるまで、モジュールをインストール。

```bash:
# ausearch -m AVC -ts hh:mm:ss | grep asterisk | audit2allow -M my-asterisk
# semodule -i my-asterisk.pp
```

# asteriskの設定
ディレクトリ ```/etc/asterisk``` 配下に設定ファイルがインストールされるが、必要なものを修正。

- asterisk.conf : 基本設定
- extensions.conf : 着信時の動作設定、電話会議の設定
- sip.conf : 内線番号の設定
- pjsip.conf : 使わないので空

## asterisk.conf

```conf:/etc/asterisk/asterisk.conf
# cat /etc/asterisk/asterisk.conf | grep -v -E "^;|^\s*;|^\s*$" 
[directories](!)
astetcdir => /etc/asterisk
astmoddir => /usr/lib64/asterisk/modules
astvarlibdir => /var/lib/asterisk
astdbdir => /var/lib/asterisk
astkeydir => /var/lib/asterisk
astdatadir => /var/lib/asterisk
astagidir => /var/lib/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk
astsbindir => /usr/sbin
[options]
runuser = asterisk		; The user to run as.
rungroup = asterisk		; The group to run as.
documentation_language = en_US	; Set the language you want documentation
```

## sip.conf
[このサイトの通り](https://qiita.com/hamham/items/9c15ae2fa5c025dc402d)

```conf:/etc/asterisk/sip.conf
# cat /etc/asterisk/sip.conf | grep -v -E "^;|^\s*;|^\s*$" 
[general]
maxexpirey=3600
defaultexpirey=3600
context=default
bindport=5060
bindaddr=0.0.0.0
srvlookup=yes
allowguest=no
disallow=all
allow=ulaw
allow=alaw
allow=gsm
language=ja
nat=force_rport,comedia
externip=asteriskサーバのグローバルアドレス
videosupport=no
[3001]
type=friend
defaultuser=3001
secret=pass
canreinvite=no
host=dynamic
dtmfmode=rfc2833
context=default
qualify=yes
callgroup=1
pickupgroup=1
mailbox=3001
[3002]
type=friend
defaultuser=3002
secret=pass
canreinvite=no
host=dynamic
dtmfmode=rfc2833
context=default
qualify=yes
callgroup=1
pickupgroup=1
mailbox=3002
```

## extensions.conf

```conf:/etc/asterisk/extensions.conf
# cat /etc/asterisk/extensions.conf | grep -v -E "^;|^\s*;|^\s*$" 
[default]
; Local SIP phones 3000-3099
exten => _30XX,1,GotoIf($["${USEVOICEMAIL}"="YES"]?use-vm)
exten => _30XX,n,Dial(SIP/${EXTEN})
exten => _30XX,n,Hangup
exten => _30XX,n(use-vm),Dial(SIP/${EXTEN},30)
exten => _30XX,n,NoOp(${DIALSTATUS})
exten => _30XX,n,GotoIf($["${DIALSTATUS}"="BUSY"]?vm-rec)
exten => _30XX,n,GotoIf($["${DIALSTATUS}"="NOANSWER"]?vm-rec)
exten => _30XX,n,GotoIf($["${DIALSTATUS}"="CHANUNAVAIL"]?vm-rec)
exten => _30XX,n,Hangup
exten => _30XX,n(vm-rec),Answer()
exten => _30XX,n,Wait(1)
exten => _30XX,n,Voicemail(${EXTEN})
exten => _30XX,n,Hangup


;[conferences]
;電話会議用に設定。8000番に電話すると複数人で電話会議が出来る
;以下2行追加
exten => 8000,1,Answer()
exten => 8000,n,ConfBridge(1234)

; Say time
exten => 117,1,Goto(saytime,1)
exten => saytime,1,Answer()
exten => saytime,2,Wait(1)
exten => saytime,3,SayUnixTime(,,Japan,YbdAPHM)
exten => saytime,4,playback(beep)
exten => saytime,5,Hangup()
```

## pjsip.conf

```conf:/etc/asterisk/pjsip.conf
# cat /etc/asterisk/pjsip.conf | grep -v -E "^;|^\s*;|^\s*$"
pjsipは使わないので空
```
# スマホアプリの利用
iphone6p, iphone8, android-tabletで確認。AGEphoneを利用
[AGEphoneのサイト](https://www.ageet.com/agephone)

## AGEphone
 sip.confにあわせて設定する。sip.confの[30xx]とdefaultuser=30xxは一致させている前提。
プロファイルで「デフォルト」を選択し、以下の設定を行う。

| 項目 | 設定値 | 備考 |
| :-- | :-- | :-- |
| ユーザID | 30xx | [30xx]に合致するようだけど、よくわかっていない |
| 表示名 | 30xx | なんでもよいようだけど、ユーザIDと一致させておく |
| 認証ID | 30xx | defaultuser&secretで認証。defaultuser |
| パスワード | **** | defaultuser&secretで認証。secret |
| ドメイン | IPアドレス | asteriskをインストールしたサーバのアドレス |

## 接続確認
- 自宅homegw内のwifiから、OK
 - homegw配下の複数台のスマホ間で内線通話できた。
 - インターネットにはmasquaradeされて、同一のグローバルIP（送信元PORTは相違）で出ていく。
 - ドメインに指定するIPアドレスは、asteriskサーバのグローバルアドレス。
- 4Gから接続
 - asteriskサーバへの接続ができず、NG
 - ４Gから、インターネットへ出ていくところでNGと想定。
 - ドメインに指定するIPアドレスは、asteriskサーバのグローバルアドレス。
- 4Gから、asteriskサーバへVPN(openvpn)接続、OK
 - asteriskサーバにopenvpn@serverを立てて、スマホからVPNでasteriskサーバへ接続。
 - VPNしている状態で、asteriskサーバへ接続、OK
 - ドメインに指定するIPアドレスは、asteriskサーバのグローバルアドレスではなく、VPNクライアントに見せているローカルアドレス(10.8.0.x)

## NTT光電話の子機
AGEphoneには、光電話の子機としての機能も実装されている。プロファイルで「光電話（東日本）」を選択したら、設定レスで光電話（固定回線）の子機として使えるようになった。。。。

asteriskサーバにVPN接続すると、４G+VPN経由で**自宅の光電話**で電話をすることができる。（なるほど、そうね）。