Asterisk

出自 ArchWiki

Asterisk 是一款完整的软件 PBX (专用分组交换机)。它运行在 Linux、BSD、Windows 和 macOS 上,并提供您期望从 PBX 获得的所有功能以及更多功能。Asterisk 通过四种协议进行 IP 语音,并且可以使用相对廉价的硬件与几乎所有基于标准的电话设备互操作。

Asterisk 提供语音邮件服务,包括目录、电话会议、交互式语音应答和呼叫排队。它支持三方通话、来电显示服务、ADSI、IAX、SIP、H.323(作为客户端和网关)、MGCP(仅呼叫管理器)和 SCCP/Skinny。

本文将向您展示如何配置一个简单的内部网络,使我们能够使用 SIP 软电话 与局域网上的另一个 SIP 软电话通话。

安装

安装 asteriskAUR 软件包。

或者,您可以安装 asterisk-lts-18AURasterisk-lts-20AUR 软件包以获得长期支持版本(当前最新的 LTS 主要版本是 Asterisk 20)。Asterisk LTS 版本的功能往往较少,但维护时间会更长。有关所有 Asterisk 版本的发布周期的完整详细信息,请参阅 Asterisk 版本 页面。

启用/启动 asterisk.service

您还需要一个 SIP 软电话 和至少两台机器。SIP 电话的推荐是 Blink (blinkAUR) 或 Linphone (liblinphone-gitAUR)。

要启用 ilbc 编解码器支持,请将以下内容添加到 PKGBUILD 的 build 区块的最开始处

cd ${pkgname}-${pkgver}/contrib/scripts
echo | ./get_ilbc_source.sh

配置

从 Asterisk 20 开始,遗留的 chan_sip 模块不再默认编译。如果您更愿意使用 chan_sip 而不是 res_pjsip,请安装 asterisk-lts-18AUR,这是最后一个构建 chan_sip 的 LTS 版本。

res_pjsip 是更新、性能更高的 Asterisk 信道模块,它支持标准的 SIP(会话发起协议)协议,这是许多运营商、电信公司、互联网电话服务提供商 (ITSP) 和企业使用的主要 VoIP(互联网协议语音)协议。但是,res_pjsip 的设置比旧的 chan_sip 复杂得多。

更广泛的 Asterisk 社区的普遍观点是,如果您已经有 chan_sip 的现有配置,则仅使用 chan_sip,同时计划升级到 res_pjsip。对于任何新安装,建议使用 res_pjsip。如上所述,chan_sip 已不再维护,甚至不进行安全修复(LTS 旧版本除外),因此新的 Asterisk PBX 管理员应使用受支持的 SIP 信道驱动程序(即 res_pjsip)。

如果您有现有的 chan_sip 配置,要在 Asterisk 20 LTS 中构建它,您可以执行以下操作:编辑 asterisk-lts-20AUR PKGBUILD 中的 build() 函数。修改以下行

PKGBUILD
make MENUSELECT_CFLAGS= OPTIMIZE= DEBUG= ASTVARRUNDIR="/run/$pkgname" NOISY_BUILD=1

在其前面加上对构建 menuselect 工具的调用,并启用 chan_sip

PKGBUILD
make menuselect.makeoptions && \
menuselect/menuselect --enable chan_sip && \
make MENUSELECT_CFLAGS= OPTIMIZE= DEBUG= ASTVARRUNDIR="/run/$pkgname" NOISY_BUILD=1

请注意,每次更新 asterisk-lts-20AUR 软件包时都需要执行此操作。

PJSIP

安装完成后,Asterisk 在 /etc/asterisk/pjsip.conf 中具有 res_pjsip 配置。Asterisk 附带的示例文件提供了一些基本示例,但并非详尽列出所有 pjsip 选项。建议读者在继续之前阅读 Asterisk Wiki 安全最佳实践文章配置 res_pjsip

本文包含一个基本的单 SIP 电话、多 SIP 中继示例,使用 Sangoma 的 SIP Station SIP 中继。配置了两个带有 SIP Station 的 SIP 中继以实现冗余,这是 SIP Station 推荐的。以下示例已使用 Sangoma/Digium D60 硬件电话进行测试,但任何符合 SIP 2.0 标准的硬电话或软电话都应该足够。

此示例假定 Asterisk PBX 服务器和 SIP 电话位于专用 IPv4 LAN 上,服务器/电话和 WAN/互联网之间有 NAT 路由器。如果您想使用 IPv6,请阅读 配置 res_pjsip 以支持 IPv6 文章。

modules.conf

首先,确保 res_pjsip.so 没有以 noload = 为前缀。在此示例中,require = 前缀使 Asterisk 在 chan_pjsip.so 加载失败时无法加载。这并非绝对必要,但除非您使用其他 VoIP 协议,否则如果 res_pjsip 未加载,则 Asterisk 加载可能没有意义。

/etc/asterisk/modules.conf
;...
require = chan_pjsip.so
;...

pjsip.conf

在深入配置 pjsip.conf 之前,请查看 PJSIP 配置向导。它对于只有一个 SIP 提供商/ITSP 的简单用例很有用,并且可以自动处理许多 pjsip 对象。

文件 pjsip.conf 是 ini 样式的配置文件,带有 [方括号中的节标题],以及哈希 (#) 或分号 (;) 作为注释字符。节标题下的每一行都是一个 键=值 对,其中节特定的键设置为指定的值。请注意,节标题可以在右方括号后附加 (!),这表示该节是模板,供以后在 pjsip.conf 中使用。要使用先前定义的模板实例化一个节,请在节标题后附加 (模板名称)

传输 (transport) 区块

为了定义用于 Asterisk 的 SIP 中继,PJSIP 具有网络 传输 的概念。根据 Asterisk Wiki,传输区块配置 res_pjsip 将如何在传输层运行。例如,它支持 TCP、UDP 或 WebSockets 等协议以及 TLS/SSL 等加密方法的配置选项。

传输区块可以任意命名,但建议命名易于记住其含义的区块。以下示例将其命名为 [transport-udp-nat],以标识此传输正在使用 UDP 进行 SIP,并且预计会遍历 NAT 设备。

/etc/asterisk/pjsip.conf
[transport-udp-nat]
type=transport  ; signifies this is a transport definition
protocol=udp  ; specifies this uses the UDP transport protocol
; this transport binds to all configured network interfaces, 
; replace with the IP address of the desired interface. 0.0.0.0 means all interfaces
bind=0.0.0.0
; =====  NOTE, the following directives are OPTIONAL
local_net=10.20.30.0/24  ; specify the networks that this Asterisk server should consider as local/LAN networks. Change this to the local LAN subnet (in CIDR notation)
local_net=127.0.0.0/8  ; specify the networks that this Asterisk server should consider as local/LAN networks (this one sets it to the IPv4 loopback network)
external_media_address=96.69.199.60  ; specify the external/WAN IP address for RDP media (audio)
external_signaling_address=96.69.199.60  ; specify the external/WAN IP address for SIP (signaling)

请注意,每个 IP 地址/端口或 IP 地址/协议映射仅允许一个传输。如果您想配置多个传输协议(例如 TCP 和 UDP),则需要将每个协议绑定到不同的 IP 地址。同样,如果您想使用相同的协议定义多个传输,则每个传输定义使用的端口需要不同。

注册 (registration) 区块

接下来,定义 SIP 中继将使用的注册。请注意,SIP Station 注册首先通过模板定义(在节名称后附加 (!))。每个模板定义了使用模板的每个节通用的设置;节本身仅包含需要为该节设置的选项。

/etc/asterisk/pjsip.conf
[sipstation-reg](!)
type=registration
transport=transport-udp-nat
contact_user=15055551234
retry_interval=60

; ==== ... several other templates and sections will appear here
; ====     including the authentication sections, etc., which are also used by the registration
; ==== ....

[siptsation-reg1](sipstation-reg)
outbound_auth=sipstation-auth1 
server_uri=sip:trunk1.freepbx.com  ; trunk1 provided by SIP Station
client_uri=sip:my_username@trunk1.freepbx.com

[siptsation-reg2](sipstation-reg)
outbound_auth=sipstation-auth2 
server_uri=sip:trunk2.freepbx.com  ;  trunk2 provided by SIP Station
client_uri=sip:my_username@trunk2.freepbx.com
认证 (authentication) 区块

在此处,定义认证模板以及用于 SIP Station 中继的特定认证节。

/etc/asterisk/pjsip.conf
[sipstation-auth](!)
type=auth
password=Super*Secret@Password!
username=my_username

; ==== ... more templates may appear here

[sipstation-auth1](sipstation-auth)
realm=trunk1.freepbx.com

[sipstation-auth2](sipstation-auth)
realm=trunk2.freepbx.com
端点 (endpoint) 区块

端点本质上是 SIP 设备(如电话或远程服务器)配置的配置文件。这定义了传输、Asterisk 拨号方案上下文(处理来自端点的呼叫)以及端点允许的音频编解码器。对于 SIP Station 中继,定义以下内容

/etc/asterisk/pjsip.conf
[sipstation-endpoint](!)
type=endpoint
transport=transport-udp-nat
context=from-external  ; Dialplan context, defined in extensions.conf or related file
disallow=all   ; disallows all codecs, including default ones, unless explicitly allowed below
allow=ulaw     ; standard G.711, uncompressed PCM codec. Uses the most bandwidth
allow=gsm      ; another standard, compressed codec. Uses less bandwidth than ulaw
; other codecs are available, and have different attributes. Some require paid licenses to use.
aors=sipstation-aors  ; AOR - Address of Record, to be defined later
;direct_media=no  ; setting this may not allow audio to pass through NAT
direct_media=yes
rtp_symmetric=yes

; ==== ... more template definitions

[sipstation-endpoint1](sipstation-endpoint)
outbound_auth=sipstation-auth1
from_domain=trunk1.freepbx.com

[sipstation-endpoint2](sipstation-endpoint)
outbound_auth=sipstation-auth2
from_domain=trunk2.freepbx.com
识别 (identify) 区块

控制 res_pjsip_endpoint_identifier_ip 模块如何确定传入数据包来自哪个端点。对于 SIP Station 中继,定义了以下内容

/etc/asterisk/pjsip.conf
[sipstation-identify](!)
type=identify
; this is the LAN IP address of the NAT router, which calls from the SIP Station
; trunks may appear to come from (because of NAT).
match=10.20.30.254/32

[sipstation-id1](sipstation-identify)
endpoint=sipstation-endpoint1
match=192.159.66.3   ;  IP address of trunk1.freepbx.com

[sipstation-id2](sipstation-identify)
endpoint=sipstation-endpoint2
match=162.253.134.142    ;  IP address of trunk2.freepbx.com
AOR (地址记录) 区块

AOR 对象(地址记录)的主要功能是告诉 Asterisk 可以联系端点的位置。如果没有关联的 AOR 区块,则无法联系端点。对于 SIP Station 中继,定义此内容

/etc/asterisk/pjsip.conf
[sipstation-aors]
type=aor
contact=sip:trunk1.freepbx.com
contact=sip:trunk2.freepbx.com
电话 (phone) 区块

最后,定义将注册到 Asterisk 的 SIP 电话所需的区块。它具有与 SIP Station 中继类似的几个区块。如果打算将多个本地 SIP 电话注册到您的 Asterisk PBX,请使用模板扩展这些区块。也可以配置远程电话(来自 WAN/互联网),但这超出了本示例的范围。

/etc/asterisk/pjsip.conf
[home-phone]
type=endpoint
transport=transport-udp-nat
context=from-internal  ;  Dialplan context that gets executed when a user dials from this phone
disallow=all
allow=ulaw
allow=gsm
auth=home-phone-auth
aors=home-phone

[home-phone-auth]
type=auth
auth_type=userpass
password=MyPhonePa$$word0
username=home-phone

[home-phone]
type=aor
max_contacts=1

管理 PJSIP

Asterisk CLI 中有几个关于 res_pjsip 的命令可用,所有命令都以 pjsip 命令为前缀。要进入 Asterisk CLI,请以 asterisk 用户身份输入以下命令

$ asterisk -rvvv

这假定 Asterisk 已经在运行(例如,通过 systemd 服务单元)。进入 Asterisk CLI 后,您将看到提示符 hostname*CLI> 。要查看可用 PJSIP 命令的列表,请键入 help pjsip

要查看 PJSIP 注册列表,请键入以下内容

hostname*CLI> pjsip show registrations
 <Registration/ServerURI..............................>  <Auth....................>  <Status.......>
---------------------------------------------------------------------------------------------

 siptsation-reg1/sip:trunk1.freepbx.com                  sipstation-auth1            Registered        (exp. 2062s)
 siptsation-reg2/sip:trunk2.freepbx.com                  sipstation-auth2            Registered        (exp. 2069s)

Objects found: 2

要查看 PJSIP 端点列表,请键入以下内容

hostname*CLI> pjsip show endpoints
                                                                                                 
 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri..........................> <Hash....> <Status> <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <Identify/Endpoint.........................................................>
        Match:  <criteria.........................>
    Channel:  <ChannelId......................................>  <State.....>  <Time.....>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
 ----------------------------------------------------------------------------------------------

 Endpoint:  home-phone                                           Not in use    0 of inf
     InAuth:  home-phone-auth/home-phone
        Aor:  home-phone                                         1
      Contact:  home-phone/sip:home-phone@10.20.30.229:506 f91928f561 NonQual         nan
  Transport:  transport-udp-nat         udp      0      0  0.0.0.0:5060

 Endpoint:  sipstation-endpoint1                                 Not in use    0 of inf
    OutAuth:  sipstation-auth1/mw3FSBsPPjQ7
        Aor:  sipstation-aors                                    0
      Contact:  sipstation-aors/sip:trunk1.freepbx.com     256c242e36 NonQual         nan
      Contact:  sipstation-aors/sip:trunk2.freepbx.com     c07c6c7180 NonQual         nan
  Transport:  transport-udp-nat         udp      0      0  0.0.0.0:5060
   Identify:  sipstation-id1/sipstation-endpoint1
        Match: 10.20.30.254/32
        Match: 192.159.66.3/32

 Endpoint:  sipstation-endpoint2                                 Not in use    0 of inf
    OutAuth:  sipstation-auth2/mw3FSBsPPjQ7
        Aor:  sipstation-aors                                    0
      Contact:  sipstation-aors/sip:trunk1.freepbx.com     256c242e36 NonQual         nan
      Contact:  sipstation-aors/sip:trunk2.freepbx.com     c07c6c7180 NonQual         nan
  Transport:  transport-udp-nat         udp      0      0  0.0.0.0:5060
   Identify:  sipstation-id2/sipstation-endpoint2
        Match: 10.20.30.254/32
        Match: 162.253.134.142/32

Objects found: 3

chan_sip

警告: chan_sip 已从 Asterisk 21 中完全删除(在 asteriskAUR 中可用),并且更广泛的 Asterisk 社区反对使用它来代替替代品 chan_pjsip。

请注意,以下说明假定您要使用已经过时的 chan_sip 模块。chan_sip 模块不再维护,但比更新的 res_pjsip 模块更容易配置。在 Asterisk 文档 中,有关于两个模块之间配置更改的摘要,以及有关如何迁移到较新模块的说明。

为了使用 chan_sip,您需要显式加载旧模块,并确保卸载较新的 chan_pjsip.so 模块。在 /etc/asterisk/modules.conf 中,调整以下内容

noload => chan_pjsip.so
noload => res_pjsip.so
; noload => chan_sip.so

将此添加到以下文件中

/etc/asterisk/sip.conf
...
[me1]
type=friend
username=me1
secret=PASSWORD
host=dynamic
context=house

[me2]
type=friend
username=me2
secret=PASSWORD
host=dynamic
context=house

这将在 house 上下文中创建我们的两个 SIP 用户 me1me2,密码为 PASSWORD。上下文将在下一步定义。

将此添加到以下文件中

/etc/asterisk/extensions.conf
[house]
exten => 100,1,Dial(SIP/me1)
exten => 101,1,Dial(SIP/me2)

这将创建上下文 house,并将分机号 100 分配给 SIP 用户 me1,将分机号 101 分配给 SIP 用户 me2

现在剩下要做的就是看看它是否有效。

保持音乐

保持音乐是一项非常棒的功能。而且再次易于安装和配置。编辑 /etc/asterisk/musiconhold.conf 并添加或确保它未被注释

[default]
mode=files
directory=mohmp3

这就是全部。只需将您最喜欢的合法获得的 MP3 复制到 /var/lib/asterisk/mohmp3

语音信箱

语音信箱是 asterisk 的另一项功能。配置方法有很多种,但本文仅介绍一种简单的方法。

创建/编辑您的 voicemail.conf

[general]
format=gsm|wav49|wav
serveremail=asterisk
attach=no
mailcmd=/usr/sbin/sendmail -t
maxmessage=180
maxgreet=60

[default]
100 => 1234,Me,me@mydomain.com

这是什么意思?大多数 [general] 都非常容易理解。但是,请注意,如果您正确设置了 postfix,则 PBX 将发送电子邮件通知用户新的语音邮件,并且如果定义了 attach=yes,它将附加该文件。

现在是实际的邮箱。格式是

mailbox => password,user,email

在本例中,我们给“我”(电子邮件 me@mydomain.com)分配了邮箱 100,密码为 1234。

现在我们必须有一种方法可以向此语音信箱留言,以及一种访问它的方法。为此,我们回到 extensions.conf 并按如下方式修改您现有的条目

exten => 100,1,Dial(SIP/me1,20)
exten => 100,n,Voicemail(u100@default)

第一个 'exten' 末尾的 20 告诉 'Dial()' 呼叫 20 秒。如果没有人接听,它将转到默认上下文中的语音信箱 100。

接下来是实际访问您的语音信箱。为此,我们添加

exten => 600,1,VoiceMailMain,s100@default

因此,当我们呼叫 600 时,应用程序 'VoiceMailMain' 会转到默认上下文中的 100。s 允许自动登录。

注意: 'VoiceMail' 应用程序有大量选项,因此建议阅读一些其他文档。这只是用于基本的家庭使用设置。另请注意,通常最好使用高于用户分机号的分机号来访问 'VoiceMail'。这样,拨打 208 的人不会碰到分机号为 205 的人的语音信箱。

连接到 PSTN

现在您已经完成了之前的设置,是时候实际连接到外部世界了。为此,您需要一个提供商,例如 OnSIP。您的提供商应提供有关连接到 asterisk 的说明,因此本节非常通用。

通用设置

sip.conf
[general]
register => username:password@sip.specific.com

[whatever]                   
fromdomain=specific.com     
host=sip.specific.com
insecure=very    ; check with provider
username=usernameduh
secret=passwordduh
type=peer
extensions.conf
[outboundwithCID]  ; this can be whatever
exten => _1NXXNXXXXXX,1,SetCIDNum(15555551234)
exten => _1NXXNXXXXXX,2,Dial(SIP/${EXTEN}@whatever)
exten => _1NXXNXXXXXX,3,Congestion()
exten => _1NXXNXXXXXX,103,Busy()

[default]  ; This should be set in your sip.conf for incoming calls

;These should to be changed to your actual number
; ie     15555555555
exten => 1NXXNXXXXXX,1,Answer()
exten => 1NXXNXXXXXX,2,Playback(ttt-weasels)
exten => 1NXXNXXXXXX,3,HangUp()
  • 在 outbound 上下文中,拨打的任何号码都将发送给您的服务提供商。优先级 2 中的 'whatever' 应与您在 sip.conf 中的内容匹配。
  • 当然,可以修改 inbound 拨号方案以执行您想要的操作。例如,您可以拥有 Dial(SIP/me1),这样当有人拨打您的号码时,他们会被路由到您计算机上的 SIP 电话。然后添加语音信箱等等。
iax.conf

第一步是登录 FWD 并启用其 IAX 端。它位于 extra features 下,请记住作者声称激活需要一段时间。

现在使用 'general' 区块中的以下内容编辑您的 iax.conf

register => FWDNUMBER:PASSWORD@iax2.fwdnet.net 
disallow = all
allow = ulaw

并在底部添加

[iaxfwd]
type=user
context=fromiaxfwd
auth=rsa
inkeys=freeworlddialup

这允许来自 FWD 的呼叫。

extensions.conf

将其放在 '[globals]' 下的顶部

FWDNUMBER=MYFWDNUMBER ; your calling number
FWDCIDNAME="MyName"; your caller id
FWDPASSWORD=MYFWDPASSWORD ; your password
FWDRINGS=sip/office ; the phone to ring
FWDVMBOX=1000 ; the VM box for this user

接下来,将其添加到 outgoing 的上下文中

exten => _393.,1,SetCallerId,${FWDCIDNAME}
exten => _393.,2,Dial(IAX2/${FWDNUMBER}:${FWDPASSWORD}@iax2.fwdnet.net/${EXTEN:3},60,r)
exten => _393.,3,Congestion

您可以将 '393' 更改为您想要的任何内容。这是您在拨打 'fwd' 号码之前拨打的内容。例如,要拨打 '744561',您将拨打 '393744561'。

最后,是来电

[fromiaxfwd]
exten => ${FWDNUMBER},1,Dial(${FWDRINGS},20,r)
exten => ${FWDNUMBER},2,Voicemail,u${FWDVMBOX}
exten => ${FWDNUMBER},102,Voicemail,b${FWDVMBOX}
注意: 如果您遇到问题,请尝试从 extensions.conf 中删除变量。这些说明来自 FWD 的站点,并且尚未经过本文作者的测试。

要尝试呼叫的分机号是 55555(志愿者接听的测试线路)和 514(会议)。

声音

声音存储在文件夹 /var/lib/asterisk/xx 中,xx 代表语言代码,例如“en”代表英语。要添加新声音,请将其复制到文件夹中。保留以下文件夹结构

/var/lib/asterisk/sounds/xx
/var/lib/asterisk/sounds/xx/digits
/var/lib/asterisk/sounds/xx/letters
/var/lib/asterisk/sounds/xx/phonetic

编辑 sip.conf 中的 language 参数

[general]
...
language=en
...

可能的声音来源是

MeetMe

MeetMe 是允许您进行电话会议的应用程序。与所有内容一样,基本设置很简单。

编辑 meetme.conf

conf => 1000

接下来是 extensions.conf

exten => 999,1,MeetMe(1000|M)

现在拨打 999 进入会议 1000。 如果那里没有人,则启用保持音乐。当有人加入会议时,它将自动消失。

注意:必须安装 zaptel 软件包才能使 MeetMe 工作。在运行 asterisk 之前安装它并运行 modprobe ztdummy。这为我们提供了没有卡片的 digium 定时,因此我们可以利用 TDM。

Asterisk 控制台和软电话

现在让我们启动 Asterisk

# asterisk -vvvvvvc

这将为我们提供带有详细输出的 Asterisk CLI。如果 Asterisk 已经在运行,您将需要使用

# asterisk -r

现在启动您的 SIP 客户端并使用 sip.conf 中的信息进行设置。切换回您的 Asterisk CLI,您应该会看到

Registered SIP 'me1' at 192.168.0.142 port 5061 expires 60

现在您应该能够从 me1 拨打 101 并与 me2 通话。

故障排除

如果您收到 404 Not Found 错误,请检查您的 extensions.conf 和您拨打的号码。