Tag: freepbx

  • 避开备案租中国大陆的服务器

    首先,如果不想备案,最简单的就是租香港的服务器。我这里特指中国大陆。

    其次,澄清一个概念:租中国大陆的服务器并非要备案。备案特指的是域名备案。

    再次,域名可以指向中国大陆的服务器,只要不建站,也可以不备案。比如,拿它做 SIP server。

    那么,建站想用中国大陆的服务器,不备案可以吗?我只想从技术上挑战一下,还成了。是在一定限定条件下的成功,但已具有极强的实操性,所以我有兴致讲一讲。

    大陆机房会抓数据包来分析 http(s) 流量是否为某个未备案的域名,是,则拦截并提示去备案。依我所见,无法 100% 抓包来分析(机房路由器算力无法 100% 抓包分析?),所以会有个别几次 http://unicped.domain 访问成功。机房的算法也是相当巧妙,所以也只是偶尔能访问成功,绝大部分次数是不成功的。

    有人说,只要改掉 http 默认的 80 端口就可以不备案建站。我已试过,此路不通,不管曾经有没有通过,反正现在不通。未加密的数据包能被分析,https 协议下的数据包是无法被分析的。所以,要避开备案,只能用 https 建站。

    好在如今 https 已是主流,http 建站可以不考虑了。需要注意的是,在 tls 1.3 出来前,https 的握手数据包是不加密的,不加密就能被分析,分析后就能阻断握手。

    好在如今的主流浏览器和主流 web server 都已支持 tls 1.3,这让不备案建站有了实操性。简单点说,就是用最新版的 web server 建个 https://any.domain。

    最后,我想用一点时间讲一讲如何不备案建一个 free SSL certificated https://freepbx.server.domain。

    1,FreePBX 安装完成后,用 http://ip.address 是可以管理的。

    2,在 System Admin > Hostname 输入域名 freepbx.server.domain,在 > Port Management 修改 Admin port 80 至一个未使用的端口,比如 48561,这样 80 端口就可以留给 LetsEncript 做 http-01 challenge。

    3,之后可以用 http://ip.address:48561 来管理。但这样去 Certificate Management 生成 LetsEncript 证书会失败,因为 FreePBX 只会用 http-01 challenge(如果会 dns-01 challenge 就好了)。

    4,我的研究表明,用 http://non-fqdn-domain:48561 来管理,就能让 FreePBX 完成 http-01 challenge。这需要在本地解析 non-fqdn-domain。

    5,在 System Admin > HTTPS Setup 启用这张证书就可以用 https://freepbx.server.domain 来管理了。

    后记:虽然成功了,但我挺纳闷的,用 http://non-fqdn-domain:48561 来管理和用 http://ip.address:48561 来管理,LetsEncript http-01 challenge 所涉及的数据包都是未加密的、无分别的、能被分析的,为什么 http://non-fqdn-domain:48561 一次就挑战成功,而 http://ip.address:48561 屡次失败。

  • Grandstream GXV3275 挺鸡肋的

    当初为了和可视 SIP 门禁机可视对讲,我买了几台当时比较稀有的大屏 SIP 话机,其中三台是 Grandstream GXV3275。我想吐槽一下:

    1,bugs 应该很多,比如总是提示 http 自动下载更新失败。好在 fireware 不需要经常更新,我忽略了这消息。

    2,web GUI 那是相当的难看,也不好用。

    3,SIP 账号改动后重新注册,到注册成功,那是相当地慢,有时好几分钟仍显示未注册,以致于我开始怀疑账号错了,东检查西检查的时候,它又突然注册成功了。

    4,接上条,可能注册时,FreePBX 检查了账号密码,认定账号合法就已经注册成功,而 Grandstream GXV3275 仍认为未注册成功,不停尝试注册,FreePBX 认为之后的注册请求都是非法的,被请求若干次后,fail2ban 就把话机的 IP 给禁了(除非事先添在白名单上)。

    谁要是想收了这三台 Grandstream GXV3275 就好了。我觉得下次再挑选 SIP 话机时,手气不会这么差。

  • Firewall and fail2ban in FreePBX

    之前一直不理解 FreePBX 里 Firewall 和 fail2ban 的关系,只感觉 FreePBX 动辄把我给关门外了,搞得我灰头土脸,为了方便起见,我干脆把 fail2ban 给关了。

    FreePBX 处于裸奔状态很久了,直到最近发生一件事:fail2ban 的日志在一天之内迅速膨胀,把硬盘写满了,于是 FreePBX 崩溃了。其中,我还是没搞懂为什么 fail2ban 禁用状态仍然在写日志?可能这就是 fail2ban 的设定。

    这个事件让我觉得应该启用 fail2ban,但我不熟 fail2ban 的命令行,甚是困惑。也是机缘巧合,这时我发现 FreePBX 激活以后(是的,很长一段时间我都不愿意激活,以为它没什么用,以为它只是为了方便 Sangoma 推销自己的付费产品),在 System Admin 或是在 Firewall 菜单页面里,就能找到 Intrusion Detection 了。Intrusion Detection 就是 fail2ban 的图形版,虽然很简化,但是足够了。

    如果在 Networks 标签页里添了一个 IP 或 Hostname 作为 Trusted Zone,但在 Intrusion Detection 标签页里没有把这个 IP 添入白名单,fail2ban 还是有可能把这个 IP 给 ban。这也是我之前经常被关门外的原因。

    那么,一个 IP 在 Networks 添一遍 Trusted Zone,还要在 Intrusion Detection 添一遍白名单,岂不是重复劳动?

    而且,Networks 可以填 Hostname,Intrusion Detection 只能填 IP,似乎灵活性差点意思?

    非也。Intrusion Detection 里 Import 选中 Trusted Zone,Trusted Zone 里的 IP 和 Hostname 就同步到白名单了。白名单只存 IP,Hostname 被自动解析了。

    自此,我只要维护好 Trusted Zone,就不再会把自己关门外了。

  • Contabo 避坑

    别误会,我不是说 Contabo 不好。

    相反,Contabo 是典型德国品质,用得让人放心。

    但是,前几天我写了一篇文章,后来发现消失了。我怀疑有人黑了我的博客,后来发现发布文章的时候恰逢 Contabo 在维护,维护结束后服务器回滚到维护之前。所以,避坑之一,避免在维护期间做事,做了白做。Contabo 确实有提前通知维护时间,但被我无视了。

    避坑之二,别订英国的 Contabo,如果一定要订,也别拿来建 PBX。

  • Do not run Asterisk as root user

    我用的 FreePBX 带的 Asterisk 是很久以前安装的,也没有关心过它是不是以 root 身份运行,直到最近被攻击。

    攻击的症状是有大量的流量访问,伴随流量不停在 /tmp 目录下生成 1-2 GB 的垃圾文件,产生文件的速度似乎跟流量大小相关。

    我不懂此次攻击的原理,但我发现原来一直以来 Asterisk 都是以 root 身份运行,我也知道这不合适。同时我也发现系统里早已有 asterisk 用户和 asterisk 组,程序、配置文件和文件夹的属主和属组都已是 asterisk 和 asterisk,也许攻击者对 Asterisk 做了提权。

    不管怎样,我得先把 Asterisk 改为非 root 身份运行。因为我的 Asterisk 以 service 方式启动,所以我在 /etc/init.d/asterisk 里增加了两行:

    AST_USER="asterisk"
    AST_GROUP="asterisk"

    重启就 OK 了。流量正常了,/tmp 下也不再生产垃圾文件,但不知道攻击有没有消失,至少漏洞堵上了。

    在堵漏洞的过程中还有个插曲:一开始还不清楚是不是操作系统层面的漏洞,我一上来就来一个

    yum update -y

    结果重启后发现系统瘫痪了,连 ssh 也进不去,只好用 console 登录,发现尝试用 service 启动任何服务时都会出现类似的错误信息。

    Error getting authority: Error initializing authority: Could not connect: Connection refused (g-io-error-quark, 44)

    据说这是 CentOS 在某个阶段升级特有的毛病。执行以下命令就好了:

    mv /var/run/dbus/system_bus_socket

    ln -s /run/dbus/system_bus_socket /var/run/dbus/system_bus_socket

  • Call to undefined function music_list()

    今天在 FreePBX 里试图编辑一个分机,点了编辑结果出现一个错误:Call to undefined function music_list()。

    好端端怎么有了这么个错误?后来发现是没有安装 Music On Hold 模块的缘故,安装并启用这个模块,错误就消失了。

    可是我不需要 Music On Hold 模块啊,记得之前也是为了应付一个错误安装了不需要的 Call Recording 模块。这样下去,模块越装越多,直到某一天 FreePBX 崩溃……

  • FreePBX 13 does not work on php 7.0.1

    前几天安装 Magento 2,竟然说要 php 5.5 以上版本。本不追新的我,想到反正要用到 remi repo,那就装个最新的 php 7.0.1。结果 Magento 2 倒是能运行,但 FreePBX 13 的 web UI 出不来了,显示成空白页。我估计是 FreePBX 所用的 php 语法不够规范,简单排查了一下,根本没看出是哪里的毛病。我估计对 php 7.0.1 来说,FreePBX 到处是毛病。虽然此时 asterisk 仍正常运行,但我不能让 web UI 长期瘫痪啊,赶紧找了个时间拆了 php 7.0.1,换上了 php 5.6。这是目前兼容性最好的版本,FreePBX 和 Magento 2 均能运行,证明对 php 环境不能过于追新。

  • Install Freepbx 13 on CentOS 7

    FreePBX Wiki 有一篇关于如何在 CentOS 7 上安装 FreePBX 13 详细的指导。我不想重复具体的步骤,只想说说如何解决在安装后出现的问题。

    我在 OpenVZ VPS 的 CentOS 7.0 minimal 环境下依次执行了 FreePBX 13 安装指导的各项命令,期间并没有发现问题,下载、编译都很顺利。安装完成以后,发现虽能访问 FreePBX web UI,但对 FreePBX 进行的第一项测试——添加一个分机,就卡住了——注册不了。这时 VPS 还未重启过,虽然指导上没有让重启,那就重启一下看看呗。重启之后,更糟,首先发现 FreePBX web UI 访问不了,然后发现 ssh 也登录不了,最后发现连 ping 也不响应。只好用 serial console 登录后排查,发现 network 服务没启动,手动重启 network 服务也失败。

    我只好把安装步骤分解,首先定位到是 yum groupinstall core 群组件造成 network 服务启动失败,然后再分解,发现是其中的 selinux* 和 NetworkManager 两个软件包的问题。定位这两个软件包花了我很长时间,这里按下不表。幸好这两个软件包也不是 FreePBX 所需要的,所以把它们卸载之后,network 服务就能正常启动了。FreePBX 安装指导提到需要将 SELinux 关闭,SELinux 也确实处于关闭状态,但它由 core 群组件安装后还是对 network 造成了困扰,卸载当然是最好的选择;NetworkManager 跟 network 冲突,似乎很久以前也碰到过,只是这次没有在第一时间想到是 NetworkManager 的问题,是地毯式排查中发现的。

    网络正常后,就能访问到 FreePBX web UI,但 dashboard 上提示无法连接到 asterisk 服务。我再回头看安装命令,其中一项是 chkconfig asterisk off。我其实挺不理解的,为什么特意不让 asterisk 自启动,当时以为安装过程中暂时将它关闭,会在后期的脚本里配置好,让 asterisk 自启动。可事实上是 asterisk 没有自启,因此我认为 chkconfig asterisk off 是原作者笔误,应该是 chkconfig asterisk on。

    另外,安装过程中特意执行了

    firewall-cmd --zone=public --add-port=80/tcp --permanent
    firewall-cmd --reload
    
    

    这是开放 80 端口。我就纳闷了——作为一个 VoIP server,仅开放 80 端口有什么用?!之后发现,5060 端口也是开放的,因此 SIP 分机注册没有问题。我没见哪条指令将它打开,估计是在某个脚本里了。但是,还有好些端口,比如 RTP 默认端口 10000-20000,不打开这些端口听筒里就没有声音。我试了一下,果然没有声音。FreePBX 安装指导没有提及更多的 firewall 的设置,这需要在安装完成后自行设置。

    执行到此,似乎就可以了,我添加了分机,并注册、互呼成功。但运行了大约半小时左右,再次添加一个分机,Apply Config 时,出现以下错误:

    Reload failed because retrieve_conf encountered an error: 1

    exit: 1
    Unable to connect to remote asterisk (does /var/run/asterisk/asterisk.ctl exist?)
    Exception: Unable to connect to Asterisk through the CLI in file /var/lib/asterisk/bin/retrieve_conf on line 24
    Stack trace:
    1. Exception->() /var/lib/asterisk/bin/retrieve_conf:24
    1 error(s) occurred, you should view the notification log on the dashboard or main screen to check for more details.

    这是因为 /var/run/asterisk/asterisk.ctl 在 asterisk 重启之后,属主、属组被修改为 root:root,而正常的应该是 asterisk:asterisk。为什么一开始的时候还能 Apply Config,一定时间后才出现问题?这个机理我搞不懂了。

    Updated 20/12/2015:这个机理我猜想是 asterisk 有一个守护进程,在异常时会重启 asterisk,用户通常不会觉察到 asterisk 已重启,但这时 Apply Config 就被拒绝。解决办法是在 /etc/asterisk/asterisk.conf 增加以下内容,可以让 /var/run/asterisk/asterisk.ctl 保持属主、属组都为 asterisk。

    [files]
    astctlpermissions = 0660
    astctlowner = asterisk
    astctlgroup = pbx
    astctl = asterisk.ctl

  • Change FreePBX default MySQL connection

    我可能吹毛求疵了:我感觉如果要修改 FreePBX 里默认的 MySQL 的连接位置好麻烦。

    我修改成 MySQL socket 方式连接,而且也修改了 socket file 的位置,然后要修改 FreePBX 好多个文件才能让 FreePBX 对接 MySQL。大部分文件属于 FreePBX 配置文件,还好办,象填表格一样填就是。但 /var/www/html/admin/modules/userman/DB_Helper.class.php 根本没为 MySQL socket 连接方式考虑,DSN 只兼容 host 连接,所以要大改 262 行(以FreePBX 2.11.0.39为例)。

    要改成多行:

    
    if (preg_match('/^unix\((.+)\)$/', $amp_conf['AMPDBHOST'], $matches) === 1) {
    	$ampdbsocket = $matches[1];
    	$dsn = "mysql:unix_socket=".$ampdbsocket.";dbname=".$amp_conf['AMPDBNAME'];
    }
    else {
    	$dsn = "mysql:host=".$amp_conf['AMPDBHOST'].";dbname=".$amp_conf['AMPDBNAME'];
    }
    
    

    直接修改程序是我最不愿意的。FreePBX 似乎也没提供安全升级的办法,所以 User Management 模块一升级,上述修改就作废,FreePBX web portal 就出错。

  • Allow specific “anonymous” inbound SIP calls

    之前所有的 SIP 服务商都是提供 SIP 注册的帐号和密码。最近碰上一个新的 SIP 服务商,购买了一个电话号码,它只让我设置 Forward to SIP Server 或 Forward to SIP URI(当然也可以转发到普通电话号码,但那是要额外收费的,不在我考虑范围之内)。

    于是,碰到了新命题:我必须在 FreePBX 的 SIP Settings 里同时启用 Allow SIP Guests 和 Allow Anonymous Inbound SIP Calls 才能收到转发过来的 SIP calls。这两项都是我不愿意启用的设置,因为存在被 SIP hackers spamming 的风险。尽管单独启用 Allow SIP Guests 据说没有太大风险,但还是接不到电话,呼叫方会收到 FreePBX 给出的语音提示:The number you have dialed is not in service. Please check the number and dial again.

    怎样才能让来自 SIP 服务商的 anonymous calls 通过,而把其他的阻挡在外?我甚至想到了启用 Allow SIP Guests 和 Allow Anonymous Inbound SIP Calls ,但用防火墙规则只允许来自特定 host / IP 的流量。这个方法我自我评价是非常 dirty,我希望是 FreePBX 的问题在 FreePBX 内部解决。

    我几乎不带希望,搞了个试验,创建了一个 SIP trunk。它跟之前注册型的 SIP trunk 的区别就是省略了 PEER Details 项里的 username, password 和 Register String。然后,同时禁用 Allow SIP Guests 和 Allow Anonymous Inbound SIP Calls,这时 Forward to SIP URI 已经能工作;再添加一条 Inbound Route,Forward to SIP Server 也能工作了。

    这个事实推翻了我对 trunk 的原有理解—— trunk 只是一条进或出的通路。现在我知道 trunk 还能“命名”符合特定条件的“匿名”来电,起到过滤的作用。

    此外,我猜想,转发型的 SIP 服务比注册型的 SIP 服务更可靠,因为转发型的 SIP 只在有来电时把数据包转发到我的 FreePBX;而注册型的 SIP 则要不时地重注册保持连接,有时连接已经断开,而 FreePBX 不知道,要等到下个周期才重注册,于是会错过来电。不知我猜想对否?请教过路的 VOIP 专家。