开源IPPBX-Asterisk部署

413 阅读8分钟

1. SIP协议与端口

SIP是用于创建、修改和终止多媒体会话(如语音、视频通话)的应用层控制协议,是VoIP(网络电话)技术的核心。

  • 未加密信令端口 5060 (UDP/TCP)

    • 说明:这是SIP协议标准的默认端口。绝大多数IPPBX和终端设备都使用此端口进行通信。
    • 特点:通信内容(包括账号、密码、呼叫的对方号码等)以明文形式在网络中传输。
    • 风险:容易被抓包工具(如Wireshark)截获和分析,存在安全风险。通常用于内部可信网络或对安全性要求不高的环境。
  • TLS加密信令端口 5061 (TCP)

    • 说明:这是用于加密SIP信令的端口。它基于TCP,并使用SSL/TLS证书对通信链路进行加密。
    • 特点:所有信令数据(包括注册认证信息)都被加密,有效防止窃听和篡改。
    • 应用:对于远程分机、跨公网注册或对安全性要求高的场景,强烈推荐使用TLS端口。

小结5060是明文端口,5061是加密端口。选择取决于你的网络安全需求。


2. 自动上线配置 (DHCP Option 66 & 67)

这是让IP电话即插即用、自动从网络服务器获取配置的关键技术,大大减少了手动配置每台电话的工作量。

  • 原理:通过在局域网中的DHCP服务器上预设两个特殊的选项(Option),告诉电话去哪里下载它的配置文件。

  • DHCP Option 66 (TFTP服务器地址)

    • 作用:直接指定一个TFTP服务器IP地址URL
    • 过程:电话通过DHCP获取IP地址时,会同时收到Option 66的信息,然后自动向这个指定的TFTP服务器请求配置文件(通常是.cfg.boot文件)。
    • 格式:可以是IP地址(如 192.168.1.10)或网址(如 http://configserver.company.com)。
  • DHCP Option 67 (引导文件名)

    • 作用:指定要从TFTP服务器下载的配置文件的完整路径和文件名
    • 过程:通常与Option 66配合使用。DHCP服务器通过Option 66告诉电话“服务器在哪”,通过Option 67告诉电话“具体下载哪个文件”。
    • 格式:通常是文件路径(如 cfg001a283456ab.cfgyealink/MAC.cfg)。很多系统支持使用电话的MAC地址作为文件名,以便为每台电话提供个性化配置。

自动配置流程总结

  1. 电话接入网络,发送DHCP请求。
  2. DHCP服务器回应,分配IP地址,并携带Option 66(TFTP服务器地址)和Option 67(配置文件名称)。
  3. 电话向指定的TFTP服务器请求指定的配置文件。
  4. 电话下载并解析配置文件,自动设置好服务器地址、分机账号、密码等所有参数,然后向IPPBX注册。
  5. 电话注册成功,即可使用。

3. 手动配置

当自动配置不可用或需要为特定电话进行特殊设置时,就需要手动配置。

  • 需清楚的参数

    1. IPPBX地址:SIP注册服务器的地址。可以是IP地址(如 192.168.1.100)或域名(如 pbx.company.com)。
    2. 注册用户/分机号:IPPBX上为你分配的分机号码(如 1001)。
    3. 认证密码:该分机号码对应的注册密码。
    4. 端口号:IPPBX监听的SIP端口。默认为5060,如果服务器使用了其他端口(包括加密端口5061),则必须填写正确。
    5. 传输协议:通常可选择UDPTCPTLS。需要与IPPBX的设置匹配。选择TLS即意味着使用加密。
  • 配置方式:通常通过电话的网页管理界面进行配置。在电话上按某个键(如 **)可以获取其IP地址,然后在电脑浏览器中输入该IP地址即可访问设置页面。


规划一:IPPBX单机部署

i.png

  • IPPBX提供SIP服务
  • iKuai软路由提供nat映射
  • ikuai路由与华硕路由之间模式isp公网环境
  • 两台sip终端注册到ippbx并实现互通

IPPBX部署步骤

服务器版本:Ubuntu 22.04.5 LTS

# 安装asterisk
sudo apt-get install asterisk
  1. 修改sip配置文件 vim /etc/asterisk/sip.conf
# 在文章末尾追加

[general]
context = default        ; 拨号计划入口
bindport = 5060          ; sip监听端口
tcpbindaddr = 0.0.0.0    ; 监听的地址
tcpenable = yes          ; 启动tcp传输
videosupport=always      ; 始终支持视频

[1001]
type = friend          ; 定义类型为friend(同时具备user和peer特性)
username=1001          ; SIP账号(用于认证)
secret = 1001          ; SIP密码
host = dynamic         ; 允许设备动态注册(非固定IP)
canreinvite = no       ; 禁止重新发起INVITE(解决NAT问题)
dtmfmode = rfc2833     ; DTMF传输方式(带内RFC2833格式)
mailbox = mailbox      ; 关联的语音信箱
transport = udp        ; 使用UDP传输协议
nat=yes                ; 启用NAT穿透支持
videosupport=always    ; 始终启用视频支持
maxcallbitrate=384     ; 最大呼叫带宽384kbps(视频通话需要)
disallow=all           ; 初始禁止所有编解码
allow = ulaw           ; 允许G.711 μ-law音频(64kbps)
allow=alaw             ; 允许G.711 A-law音频(64kbps)
allow=h263             ; 允许H.263视频编码
allow=h264             ; 允许H.264视频编码(主流高清编码)

[1002]
type = friend
username=1002
secret = 1002
host = dynamic
canreinvite = no
dtmfmode = rfc2833
mailbox = mailbox
transport = udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264

[1003]
type = friend
username=1003
secret = 1003
host = dynamic
canreinvite = no
dtmfmode = rfc2833
mailbox = mailbox
transport = udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264

2. 修改拨号计划配置文件 vim /etc/asterisk/extensions.conf

# 在文章末尾追加

[general]
static=yes        ; 配置文件为静态(运行时不会自动重载)
writeprotect=no   ; 允许通过AMI动态修改拨号计划(生产环境建议设为yes)

[default]         ; 默认呼叫上下文(路由入口)

; 分机1001的呼叫处理流程
exten => 1001,1,Answer()            ; 应答来电(第1步)
exten => 1001,n,Dial(SIP/1001,20,tr)   ; 呼叫SIP设备1001(n=下一步)
                                         ; 参数说明:
                                         ;   SIP/1001 - 呼叫通道
                                         ;   20       - 振铃超时(秒)
                                         ;   tr       - 启用语音信箱转移
exten => 1001,n,Hangup()            ; 挂断呼叫(最后一步)


exten => 1002,1,Answer()
exten => 1002,n,Dial(SIP/1002,20,tr)
exten => 1002,n,Hangup()


exten => 1003,1,Answer()
exten => 1003,n,Dial(SIP/1003,20,tr)
exten => 1003,n,Hangup() 
                        
  1. 进入调试模式
# 重启服务
systemctl restart asterisk.service 

# 进入控制台
asterisk -r

# 查看sip注册情况
*CLI> sip show peers

# 解绑1001
*CLI> sip unregister 1001

ikuai映射服务配置

image.png

下载安卓客户端

客户端选用Linphone Download - Linphone

IMG_20250715_142741.jpg

拨打测试

IMG_20250715_142935.jpg

注册抓包

image.png

规划二:IPPBX SIP中继 双机部署

i2.png

  1. IPPBXB 系统

    • 提供 SIP 服务,包含主机号:
      • 1001(专用于与 IPPBXA 互通)
      • 1002(终端注册号)
      • 1003(备用号)
  2. IPPBXA 系统

    • 提供 SIP 服务,包含主机号:
      • 2001(专用于与 IPPBXB 互通)
      • 2002(终端注册号)
  3. 网络互联

    • iKuai 软路由为 IPPBXB 提供 NAT 映射服务。
    • iKuai 路由与华硕路由逻辑互通,形成统一通信环境。
  4. 终端通信逻辑

    • 终端 A:注册到 IPPBXB,使用主机号 1002
    • 终端 B:注册到 IPPBXA,使用主机号 2002
    • 互通路径
      • 终端 1002(IPPBXB)→ 通过主机号 1001 连接 IPPBXA → 到达终端 2002
      • 反向路径同理,实现双向通话。

IPPBX-A sip.conf配置

[general]
context=internal        ; 拨号计划入口
bindport=5060          ; sip监听端口
tcpbindaddr=0.0.0.0    ; 监听的地址
tcpenable=yes          ; 启动tcp传输
videosupport=always      


[ippbx-b-trunk]
type=peer
host=172.16.40.220      ; IPPBX-B 的IP地址
username=1001           ; IPPBX-B提供互联的分机号
secret=1001             ; IPPBX-B提供互联的分机号的密码
context=from-ippbx-b
transport=udp
qualify=yes
insecure=invite
disallow=all
allow=ulaw
allow=alaw


[2001]
type = friend
username=2001
secret = 2001
host = dynamic
context=internal
canreinvite = no
dtmfmode = rfc2833
mailbox = mailbox
transport = udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264


[2002]
type = friend
username=2002
secret = 2002
host = dynamic
context=internal
canreinvite = no
dtmfmode = rfc2833
mailbox = mailbox
transport = udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264

IPPBX-A extensions.conf配置

; 呼出规则(通过中继拨打外线)
[from-ippbx-b]
exten => _100X.,1,Dial(SIP/${EXTEN}@ippbx-b-trunk)  ; 通过中继呼出
exten => _200X,1,Goto(internal,${EXTEN},1)

; 呼入规则(处理来自中继的来电)
[internal]
exten => 2001,1,Answer()  
exten => 2001,n,Dial(SIP/2001,20,tr)
exten => 2001,n,Hangup

exten => 2002,1,Answer()
exten => 2002,n,Dial(SIP/2002,20,tr)
exten => 2002,n,Hangup

exten => _100X,1,Dial(SIP/${EXTEN}@ippbx-b-trunk)

IPPBX-B sip.conf配置

[general]
context=internal
bindport=5060
tcpbindaddr=0.0.0.0
tcpenable=yes
videosupport=always

[1001]
type=friend
context=internal
username=1001
secret = 1001
host = dynamic
canreinvite=no
dtmfmode=rfc2833
mailbox=mailbox
transport=udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264

[1002]
type=friend
context=internal
username=1002
secret=1002
host=dynamic
canreinvite=no
dtmfmode=rfc2833
mailbox=mailbox
transport=udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264

[1003]
type=friend
username=1003
secret = 1003
host = dynamic
canreinvite=no
dtmfmode=rfc2833
mailbox=mailbox
transport=udp
nat=yes
videosupport=always
maxcallbitrate=384
canreinvite=no
disallow=all
allow = ulaw
allow=alaw
allow=h263
allow=h264


[ippbx-a-trunk]
type=peer
host=172.16.40.223
username=2001
secret=2001
context=from-ippbx-a
transport=udp
qualify=yes
insecure=invite
disallow=all
allow=ulaw
allow=alaw

IPPBX-B extensions.conf配置

[general]
static=yes
;writeprotect=no

[internal]

exten => 1001,1,Answer()
exten => 1001,n,Dial(SIP/1001,20,tr)
exten => 1001,n,Hangup

exten => 1002,1,Answer()
exten => 1002,n,Dial(SIP/1002,20,tr)
exten => 1002,n,Hangup

exten => 1003,1,Answer()
exten => 1003,n,Dial(SIP/1003,20,tr)
exten => 1003,n,Hangup

exten => _200X,1,Dial(SIP/${EXTEN}@ippbx-a-trunk)


[from-ippbx-a]
exten => _100X,1,Goto(internal,${EXTEN},1)
exten => _200X,1,Dial(SIP/${EXTEN}@ippbx-a-trunk)

配置验证

image.png

image.png

IMG_20250716_144641.jpg