耗时半个多月,从FreePBX换到FreeSwitch,再到FusionPBX,最后再回到FreePBX,终于把集团电话搭建完毕。在此记录一下踩坑的过程。
1. FusionPBX编译的坑
按照官网的步骤,编译非常简单,简单到令人发指,一共两句话。(https://www.fusionpbx.com/download)
wget -O - https://raw.githubusercontent.com/fusionpbx/fusionpbx-install.sh/master/debian/pre-install.sh | sh;
cd /usr/src/fusionpbx-install.sh/debian && ./install.sh
坑就坑在,所有东西都在github,某些组件使用git clone下载源代码安装,某些组件使用wget下载源码。正常讲,当前网络环境极大概率会卡在某一步,比如在我的服务器上无论挂不挂代理,pre-install.sh都无法下载,提示需要认证。
贴士A: 开始敲命令前,挂一个靠谱代理(比如我的场景里,远程到服务器上,反过来挂我本机的代理)。
export ALL_PROXY="socks5://10.1.0.129:10810"
贴士B:发现卡在下载pre-install.sh时,可以手动下载下来,传到服务器上再执行,下载完成后,代码全部在/usr/src/fusionpbx-install.sh这个目录下,不同的操作系统对应各自的目录,因为官方推荐系统是Debian 11,所以安装了Debian,并且所有脚本都是在/usr/src/fusionpbx-install.sh/debian目录下面)。
贴士C:在安装脚本运行中途,仔细观察卡住的地方,无论是wget卡住,还是git clone卡住,都可以像贴士B里一样,手动下载代码并上传到服务器上脚本指定的位置(一般是在/usr/src/freepbx下面),最后注销脚本里wget/git clone那一句(非常重要);如果不知道卡在具体哪个脚本,可以根据屏幕上的提示,用grep -R 查找整个目录,据此来定位应该修改哪个脚本。
比如我在安装的时候,下载sofia-sip源码一直失败,所以直接根据脚本里的地址手动下载并上传,然后注释掉了wget语句,顺利进行到下一步;同样,在git clone下载fusionpbx源码时也会卡住,也用类似的手段处理。
2. FusionPBX网关注册的坑
另外一个非常折腾的过程是SIP注册:ISP给到的信息只有账号、密码、注册服务器、代理服务器、IP、网关、DNS。
贴士D:拿到账号信息后,先用SIP客户端/IP电话直接注册,确认能够注册上,并且能正常呼入和打出,线路和账号没有任何问题,然后才能开始搭建工作。
客户端和语音系统的侧重不一样,在使用的时候,前者的设计目标是让客户配上最基本的参数就可以接通,绝大多数参数具有适用于大多数场景的默认设置;而后者更灵活,功能更强大,所以很多参数需要用户自己根据需求进行微调。
运营商线路在FreeSwitch里叫Gateway,在FreePBX里叫Trunk,实际上就是同一个东西,指的就是出局线路。当然对端除了可以是运营商,也可以是另一套话务系统。
线路的注册也是有非常多坑的地方,正如前面介绍的那样,ISP只提供有限的几个必备参数,但是实际注册的时候,需要使用十几个,甚至几十个其它参数。而语音系统本身因为灵活性高,参数配置更自由,所以就需要更多的试错努力。
也不完全是盲目尝试,FusionPBX中可以用sofia profile external siptrace on来打开日志,根据注册报文来观察服务器的响应。
贴士E:以江苏移动为例,FusionPBX里的Gateway需要配置如下几项
- Proxy配置为ims.js.chinamobile.com(网页上的名字叫Proxy,其实是注册服务器);
- Realm配置为ims.js.chinamobile.com;
- UserName配置为+86xxxxxx (以+开头,包含国家代码、区号的完整电话号码);
- AuthUserName配置为 UserName@ims.js.chinamobile.com;
- Outbound Proxy才是真正的代理,配置为Proxy地址221.130.109.160;
- Registar Proxy也配置为Proxy地址221.130.109.160。
3. FreePBX网关注册的坑
和配置FusionPBX一样,重点仍然是注册,一定不会一次就通,参数只能在不断被Reject的过程里来修正:FreePBX没有Realm参数;FusionPBX里的分出局和注册代理,FreePBX只有,也只需要一个Outbound Proxy选项。
贴士F:FreePBX中,Trunk类型强烈建议用chan_pjsip,不要用chan_sip(如果有这个选项的话),较新的版本里chan_sip直接被弃用了。
贴士G:还是以江苏移动为例,FreePBX的Trunk需要配置如下几项
- Dial Number Manipulation Rules,没有特殊需求的话,全部留空,在match pattern中填 X.
[pjsip settings – General]
- UserName配置为+86xxxxxx (以+开头,包含国家代码、区号的完整电话号码);
- AuthUserName配置为 UserName@ims.js.chinamobile.com;
- Authentication选择Outbound,出局认证;
- Registration选择为Send,表示主动向服务器注册,注册以后服务器就知道你在哪里了;
- SIP Server填ims.js.chinamobile.com;
- SIP Server Port,标准5060端口,下面的协议选udp;
[pjsip settings – Advanced]
- Send Line in Registration选No;
- Qualify Frequency填0;
- Outbound Proxy填 sip:221.130.109.160\;lr 实际就是追加一个lr参数,用分号连接,但又需要转义,所以最后会得到这么奇怪的一个东西;
- Contact User,填上面的UserName +86xxxxxx
- Client URI,填 sip:+86xxxxxx@ims.js.chinamobile.com
- Server URI,填 sip:ims.js.chinamobile.com
- AOR Contact,填 sip:+86xxxxxx@wanip:5060 ,把wanip换成公网地址,大概就是这个参数,起到了和FusionPBX realm类似的效果
- Trust RPID/PAI选Yes
- Send RPID/PAI选Both
- Force rport选No
正常注册以后,只能说明我们的系统已经连接到了ISP。想要正常通信,还要求其它参数双方协商也成功才行,这就来到另一个大坑。
4. FreePBX语音编码的坑
所有工作完成后,所有电话都出现了相同的问题,打进全部正常,呼出如果碰到4G手机会直接挂断(直到现在,连是否真的问题出在4G都不确定,也可能是联通号码的原因),查询日志只能看到提示服务器返回一个很笼统的487错误。
查了很久,最后勉强找到一个帖子,有人碰到了相似的问题,别人帮他定位到了是因为一个G729编码的时间设置(maxptime)和运营商不匹配,但是FreePBX并不支持修改这个编码时间,因为它已经写死在了代码里。最后解决起来也简单,换成其它编码,不用G729就行。
贴士H: 编码也很重要,需要两边都支持(话机-PBX, PBX-ISP)。