松実のStudy Knowledge

Windows 11 + SoftEther + Ubuntu VM + Asteriskで自宅SIPサーバーを構築したメモ

目的

自宅のWindows 11マシン上にLinux VMを立て、Asteriskで最小構成のSIPサーバーを作成しました。 まずはLAN内でWindowsとスマホのソフトフォンを登録し、内線101 / 102で相互通話できるところまでを目標にしました。

  • LAN内でWindowsとスマホのソフトフォンを登録できる
  • 内線101 / 102で相互通話できる
  • SoftEther VPN経由の端末からも利用できるようにする
  • 既存のApache / VPN構成は維持する

※この記事では、IPアドレス、DDNS名、ユーザー名、パスワードなどの固有情報は記事用にマスクしています。 サンプルのパスワードはそのまま使わず、実運用では必ず強い値に変更してください。

構成

Windows 11上にSoftEther VPN ServerとHyper-Vを置き、Hyper-V上のUbuntu VMにAsteriskを入れました。 Ubuntu VMはHyper-Vの外部仮想スイッチで公開側LANに直接参加させています。

Windows 11 と SoftEther と Ubuntu VM と Asterisk を使った自宅 SIP サーバー構成図
[Internet]
    |
[モデム兼ルーター / NAT]
 ├─ [Apacheサーバー]          192.168.xxx.xxx
 ├─ [Windows 11]             192.168.xxx.xxx
 │    ├─ SoftEther VPN Server
 │    └─ Hyper-V
 │         └─ Ubuntu VM      192.168.xxx.xxx
 │              └─ Asterisk
 └─ [内側ルーター]
      └─ [家庭内端末]         192.168.xxx.0/24

VPN側

  • SoftEther SecureNATを利用
  • VPNクライアント帯: 192.168.xxx.0/24
  • 仮想ホストIP: 192.168.xxx.xxx
  • DHCP配布範囲: 192.168.xxx.xxx - 192.168.xxx.xxx

採用したソフト

VPN

  • SoftEther VPN Server
  • Windows 11上に構築

SIP / PBX

  • Asterisk
  • Ubuntu VM上に構築

ソフトフォン

  • Windows: Linphone
  • スマホ: Linphone

Ubuntu VMのネットワークを外部スイッチに変更

最初、Hyper-VのVMはNAT側にいて172.28.x.xのIPを取っていました。 この状態だとLAN内の他端末から直接SIP登録しづらいため、Hyper-Vの仮想スイッチを外部仮想スイッチへ変更しました。

変更後のIPは次のコマンドで確認しました。

ip -4 a

結果、Ubuntu VMが公開側LANのアドレスを持ち、LANに直接参加する形になりました。

192.168.xxx.xxx/24

Asteriskをインストール

途中、aptの依存関係が壊れていてそのままでは入らなかったため、先にパッケージ状態を復旧してからAsteriskを入れました。

aptの復旧

sudo apt update
sudo apt --fix-broken install
sudo dpkg --configure -a

インストール

sudo apt install -y asterisk

状態確認

sudo systemctl status asterisk --no-pager
sudo ss -lunp | grep 5060
  • asterisk.serviceがactive (running) になっている
  • 0.0.0.0:5060/udpをAsteriskがListenしている

Asteriskの最小設定

今回はPJSIPを使い、内線101と102を用意しました。 SIP登録後に通話とメッセージ確認までできるよう、最小限のendpoint / auth / aorとdialplanを設定しています。

pjsip.conf

sudo tee /etc/asterisk/pjsip.conf > /dev/null <<'EOF'
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060

[101]
type=endpoint
context=internal
message_context=messages
disallow=all
allow=ulaw
allow=alaw
auth=101
aors=101
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
callerid="101" <101>

[101]
type=auth
auth_type=userpass
username=101
password=pass101

[101]
type=aor
max_contacts=1
remove_existing=yes

[102]
type=endpoint
context=internal
message_context=messages
disallow=all
allow=ulaw
allow=alaw
auth=102
aors=102
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
callerid="102" <102>

[102]
type=auth
auth_type=userpass
username=102
password=pass102

[102]
type=aor
max_contacts=1
remove_existing=yes
EOF

extensions.conf

sudo tee /etc/asterisk/extensions.conf > /dev/null <<'EOF'
[internal]
exten => 101,1,Dial(PJSIP/101,20)
 same => n,Hangup()

exten => 102,1,Dial(PJSIP/102,20)
 same => n,Hangup()

[messages]
exten => 101,1,NoOp(Message for 101)
 same => n,Set(MESSAGE(from)=sip:102@192.168.xxx.xxx)
 same => n,MessageSend(pjsip:101,${MESSAGE(from)})
 same => n,Hangup()

exten => 102,1,NoOp(Message for 102)
 same => n,Set(MESSAGE(from)=sip:101@192.168.xxx.xxx)
 same => n,MessageSend(pjsip:102,${MESSAGE(from)})
 same => n,Hangup()
EOF

反映

sudo systemctl restart asterisk

Asterisk側の確認コマンド

CLIに入る

sudo asterisk -rvv

PJSIPの確認

pjsip show endpoints
pjsip show contacts
pjsip show transports

SIP / RTPログ確認

pjsip set logger on
rtp set debug on

Linphoneの設定

Windows側101

Username: 101
Password: pass101
Domain: 192.168.xxx.xxx
Display name: 101
Transport: UDP
Authentication ID: 101
Registrar URI: sip:192.168.xxx.xxx:5060
Outbound SIP Proxy URI: 空欄

スマホ側102

Username: 102
Password: pass102
Domain: 192.168.xxx.xxx
Display name: 102
Transport: UDP
Authentication ID: 102
Registrar URI: sip:192.168.xxx.xxx:5060
Outbound SIP Proxy URI: 空欄

UFWの設定

LANとVPNの両方からSIP登録とRTP音声を通せるようにしました。 5060/udpはSIP登録、10000-20000/udpはRTP音声用です。

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow from 192.168.xxx.0/24 to any port 22 proto tcp
sudo ufw allow from 192.168.xxx.0/24 to any port 5060 proto udp
sudo ufw allow from 192.168.xxx.0/24 to any port 10000:20000 proto udp

sudo ufw allow from 192.168.xxx.0/24 to any port 5060 proto udp
sudo ufw allow from 192.168.xxx.0/24 to any port 10000:20000 proto udp

sudo ufw enable
sudo ufw status verbose
  • 5060/udp: SIP登録
  • 10000-20000/udp: RTP音声
  • LAN側セグメントからSIP / RTPを許可
  • VPNクライアント帯からSIP / RTPを許可

動作確認の流れ

LAN内での確認

  1. WindowsのLinphoneで101を登録
  2. スマホのLinphoneで102を登録
  3. pjsip show contactsで両方見えることを確認
  4. 101から102に発信
  5. 102から101に発信
  6. 双方向で音が聞こえることを確認

VPN経由での確認

  1. スマホをSoftEther VPNに接続
  2. VPN側IPがVPNクライアント帯になっていることを確認
  3. Linphoneの接続先はUbuntu VMのLAN側IPのままにする
  4. 登録 / 発信を確認

ハマったポイント

Hyper-VのVMがNAT配下にいた

最初はVMのIPが172.28.x.xになっていました。 このままだとSIPの確認や他端末からの到達性が面倒だったため、外部仮想スイッチに切り替えてLAN側IPを持たせました。

外部スイッチに変えた直後、NICが死んだように見えた

切り替え直後にloしか見えず、eth0がNO-CARRIER / state DOWNになりました。 Hyper-V側で実NICに正しくつながっていなかったため、外部スイッチの物理NICを見直して再接続しました。

Asteriskのインストール時にapt依存関係が壊れていた

apt install asteriskが失敗し、apt --fix-broken installを要求されました。 aptの状態を直してからAsteriskをインストールしました。

SoftEtherはつながるのにスマホVPNが認証失敗した

スマホからVPN接続すると「認証に失敗しました」と表示されました。 SoftEtherのDefault Virtual HUBが未設定だったため、IPsec / L2TP設定でDefault Virtual HUBをHOMEVPNに設定しました。

443はApacheが使っていたのでSoftEther側には使えなかった

Apacheがすでに443を使っていたため、Apacheは443、SoftEtherは5555 / 992、スマホVPNはUDP 500 / 4500 / 1701に分けました。

SIP登録はできるのに音が聞こえなかった

呼び出しや着信通知はできるのに音声が聞こえない状態になりました。 direct_media=no、rtp_symmetric=yes、force_rport=yes、rewrite_contact=yesを設定し、UFWで10000-20000/udpを許可しました。

101 / 102が登録済みなのに再登録で403 Forbiddenになった

max_contacts=1に対して古いcontactが残っていたため、remove_existing=yesを追加しました。

LinphoneのチャットメッセージがAnonymousになった

通話は101 / 102で見えるのに、メッセージだけAnonymous扱いになりました。 message_context=messagesを設定し、MessageSend() の前にMESSAGE(from) を明示しました。

VPN経由端末はUFWを開けても最初は登録できなかった

VPN接続でVPN側IPは取れているのにSIP登録できませんでした。 UFWの許可元にVPNクライアント帯が入っていなかったため、VPN帯から5060/udpと10000-20000/udpを許可しました。

最終的に動いた構成

  • Asterisk: Ubuntu VM上で稼働
  • Windows Linphone: 101
  • スマホLinphone: 102
  • LAN内通話OK
  • VPN経由でも登録 / 通話OK
  • メッセージ送信時のAnonymousも解消

まとめ

今回の構成では、最初から全部を一気にやろうとせず、Ubuntu VMをLANに直接出すところから順に確認したのが一番分かりやすかったです。

  1. Ubuntu VMをLANに直接出す
  2. Asteriskを最小構成で起動する
  3. Linphoneで101 / 102を登録する
  4. 通話を通す
  5. UFWを戻す
  6. VPNクライアント帯を許可する
  7. メッセージ表示を整える

特にハマりやすかったのは、Hyper-Vのネットワーク方式、SoftEtherのDefault Virtual HUB、UFWのRTP開放、Asteriskのmax_contacts、MESSAGEの送信元表示でした。

参考用コマンド一覧

Asterisk状態確認

sudo systemctl status asterisk --no-pager
sudo ss -lunp | grep 5060
sudo asterisk -rvv

Asterisk CLI

pjsip show endpoints
pjsip show contacts
pjsip show transports
pjsip set logger on
rtp set debug on

Ubuntu IP確認

ip -4 a
ip route

UFW確認

sudo ufw status verbose
sudo ufw status numbered

Advertisement