环境准备
- x86_64或者arm64 cpu的硬件。本人使用的orange pi5 max(rk3588 arm64).
- linux环境,这里用ubuntu 24.04为例。
- docker容器。k8s这类基于容器的服务也可以使用。这里以docker为例。
- 移远的4g模块,这里用的
EC20CEFAG-512-SGNS这个全能版。 - 项目地址:https://github.com/scjtqs2/docker-asterisk-freepbx
功能说明
- 短信转发支持,支持多个渠道的短信转发。“企业微信”、“gotify”、”bark”、”ntfy”、”email”、”feishu”、“钉钉”、“telegram bot”。
- 转发支持正则和关键词过滤
- 支持短信发送,通过api发送/回复短信
- 简单的短信web管理界面,可以查询短信的收发记录。
- 通过sip接听和拨打电话(基于asterisk,需要通过freepbx自行配置账号密码)
通过docker-compose部署,这里我给一个demo配置,具体配置以github仓库的demo为准
version: '3'
services:
freepbx:
image: scjtqs/asterisk-freepbx:latest
container_name: freepbx
ports:
- "1283:80"
- "1284:443"
- "4569:4569/udp"
- "5060:5060/tcp"
- "5060:5060/udp"
- "10000-10010:10000-10010/udp" #通话媒体端口,需要自行在freepbx后台设置范围。太多了docker映射不过来,劲量小吧。
- "1285:1285" # sms_send服务端口,也是短信管理页面的短信。SMS_SEND_PORT
environment:
- TZ=Asia/Shanghai
- DBENGINE=mysql
- DBNAME=asterisk # 预先创建的asterisk数据库
- DBHOST=192.168.123.123 # 外部的mysql的部署就不多描述了
- DBPORT=3306
- CDRDBNAME=asteriskcdrdb # 预先创建的cdr数据库
- DBUSER=asterisk # mysql 用户名
- DBPASS=asteriskPass123 # mysql密码
- USER=asterisk # 内部执行用户,不要修改
- GROUP=asterisk # 内部执行用户组,不要修改
- WEBROOT=/var/www/html # 不做修改
- ASTETCDIR=/etc/asterisk # 不做修改
- ASTMODDIR=/usr/lib64/asterisk/modules # 不做修改
- ASTVARLIBDIR=/var/lib/asterisk # 不做修改
- ASTAGIDIR=/var/lib/asterisk/agi-bin # 不做修改
- ASTSPOOLDIR=/var/spool/asterisk # 不做修改
- ASTRUNDIR=/var/run/asterisk # 不做修改
- AMPBIN=/var/lib/asterisk/bin # 不做修改
- AMPSBIN=/usr/sbin # 不做修改
- AMPCGIBIN=/var/www/cgi-bin # 不做修改
- AMPPLAYBACK=/var/lib/asterisk/playback # 不做修改
- AT_PORT=/dev/ttyUSB2 # 第一次运行生成配置时有效。后面需要自行去./asterisk/etcasterisk/quectel.conf 下去手动修改
- AUDIO_PORT=/dev/ttyUSB1 # 第一次运行生成配置时有效。后面需要自行去./asterisk/etcasterisk/quectel.conf 下去手动修改
- FORWARD_SECRET=YourFowdaardSecret # 短信推送通信秘钥
- SMS_SEND_PORT=1285 # sms_send的go程序的http端口,提供接受asterisk短信(转发出去)和发送短信的api。
- PHONE_ID=SIM1_1861xxxxxxxxxx # 短信推送的时候标识字段。如果插件不能获取到手机号,就会取这个值。
- SMTP_SERVER=smtp.mycompany.com:587 # 您的SMTP服务器地址和端口
- [email protected] # 您的邮箱账号
- SMTP_PASSWORD=YourSecureAppPassword # 您的邮箱密码
- SMTP_SSL=false # 是否是走的ssl模式,比如465端口。.587是tls,不需要开这个。
- ACME_DNS_TYPE=dns_cf # acme.sh dns证书的验证方式。这里demo是cloudflare
- ACME_ENABLE=true # 是否需要通过acme的dns方式帮你生成一个https证书
- [email protected] # 用于acme.sh注册的邮箱
# dns_cf需要的环境变量 demo。将你选择的ACME_DNS_TYPE需要的环境变量放下面。其他方式的方对应变量名称
- CF_Token=124
- CF_Account_ID=568
- [email protected]
- FQDN=sip.domain.com # 需要生成证书的域名
- APACHE_HTTP_PORT=80
volumes:
- ./data:/data # 短信db、转发日志等
- ./asterisk/varasterisk:/var/lib/asterisk # asterisk的lib文件夹
- ./asterisk/etcasterisk:/etc/asterisk # asterisk的 /etc/asterisk的文件夹内容
- ./asterisk/logs:/var/log/asterisk # asterisk的日志
- ./asterisk/wwwdata:/var/www/html # freepbx的内容
- ./asterisk/records:/var/spool/asterisk/monitor
- ./forward.yaml:/data/config/forward.yaml # 转发配置文件 # 转发短信到其他平台 配置文件参考 https://github.com/scjtqs2/docker-asterisk-freepbx/blob/main/forward.yaml
restart: always
privileged: true # 开了它,融器才具备root权限,能读取到/dev/ttyUSBx的数据
在同级目录里创建一个 forward.yaml文件,用于配置短信转发。参考配置:
# 如果有all这个配置,就是默认所有短信都会转发给这个机器人,建议发送给管理员,或者直接删除关闭
all:
rule: all
type: all
notify: wechat
url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxx
# 从上到下依次为 项目名称、规则(使用关键字匹配)、匹配方式(后续可能支持正则)、机器人url
测试:
rule: 测试DDD
type: keyword
notify: wechat
url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxx
工单号:
rule: "\d{8}" # 匹配8位数字
type: regex
notify: gotify
url: https://gotify.example.com
token: your_app_token
bark:
notify: bark
type: all
rule: all
url: "https://api.day.app/xxxx"
gotify:
notify: gotify
type: all
rule: all
url: "https://gotify.example.com"
token: "your_app_token"
ntfy:
notify: ntfy
type: all
rule: all
url: "https://ntfy.sh"
topic: "your_topic"
token: "your_ntfy_token" # 可选,私有化部署需要
email:
notify: email
type: all
rule: all
smtp_host: "smtp.qq.com"
smtp_port: "587"
username: "[email protected]"
password: "授权码"
from: "[email protected]"
to: "[email protected]"
feishu:
notify: feishu
type: all
rule: all
url: "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"
dingding:
notify: dingtalk
type: all
rule: all
url: "https://oapi.dingtalk.com/robot/send?access_token=xxx"
telegram:
notify: telegram
type: all
rule: all
bot_token: "123456789:AAFxxxxxxxx"
chat_id: "-1001234567890"
proxy: "http://proxy.example.com:8080" # 或者 "socks5://127.0.0.1:1080" 或者留空
注意事项
- 需要另外独立部署一个mysql数据库,这里就不写了。如果不懂,可以去问ai。
- 需要在mysql数据库里面创建两个数据库:
asterisk和asteriskcdrdb - 4g模块尽量使用最新的固件
- 如果你想要到公网使用,需要透传
5060的tcp和udp(具体端口,可以在freepbx里面配置,如果有修改,docker-compose.yaml里面也需要修改对应的端口)、10000-10010的udp端口(这个范围默认是10000-20000,端口范围太广,docker转发会造成卡死,个人使用,建议修改到10000-10010就够用了,毕竟你个人使用不至于10个并发通话存在。如有有特殊需求,请自行调整)
简单流程说明
准备好你的环境
- 配置好你的mysql数据库
- 创建好`forward.yaml`和`docker-compose.yaml`
- 把4g模块插入usb转接板,插入sim卡,接上4g天线,插入到你的设备上。通过`ls /dev/ttyUSB*`可以看到`/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3`这4个设备
配置你的4g模块
安装minicom: apt-get install minicom
用它去连接ttyusb端口
| 接口 | 描述 |
|---|---|
| /dev/ttyUSB0 | |
| /dev/ttyUSB1 | PCM语音,GPS信号 |
| /dev/ttyUSB2 | 控制命令 |
| /dev/ttyUSB3 | 网络,备用控制命令 |
执行minicom -D /dev/ttyUSB2进入控制界面:

重置模块
输入命令 at+qprtpara=3 重置一下模块,以避免模块里面有上一个用家的错误配置。 重置完以后用 AT+CFUN=1,1 重启。
等待模块重启完成以后,再进入 AT 接口,这时候可以先看一下 SIM 卡是否注册成功:
AT+COPS?
+COPS: 0,0,"CHN-UNICOM",7
OK
AT+QNWINFO
+QNWINFO: "FDD LTE","46001","LTE BAND 3",1850
OK
配置VoLTE
首先需要使用 AT+QCFG=”ims”,1 来开启 VoLTE, 然后可以使用 AT+QMBNCFG=”List” 查看一下 VoLTE 的配置文件,一般会返回下面的输出:
+QMBNCFG: "List",0,0,0,"ROW_Generic_3GPP",0x0501081F,202112292
+QMBNCFG: "List",1,1,1,"CU-VoLTE",0x05011508,202201063
+QMBNCFG: "List",2,0,0,"VoLTE_OPNMKT_CT",0x050113FC,202201101
+QMBNCFG: "List",3,0,0,"Volte_OpenMkt-Commercial-CMCC",0x05012071,202201063
输入ATI命令,可以查看你的ec20cefag-512-sgns的固件版本。例如EC20CEFAGR08A02M4G。这是一个R08的固件。另外有部分人的是R06的固件。
如果你是R06的固件,那么你需要执行下面流程,手动指定ROW_Generic_3GPP配置文件才能正常使用。R08的可以正常自动识别。:
- 关闭自动选择mbn文件:AT+QMBNCFG=”AutoSel”,0
- 反激活当前的mbn:at+qmbncfg=”deactivate”
- 强制选择3gpp:AT+QMBNCFG=”select”,”ROW_Generic_3GPP”
- 重启:AT+CFUN=1,1
重启完了以后,可以使用 AT+QCFG=”ims” 查询 VoLTE 激活状态。 如果是 +QCFG: “ims”,1,1,就代表 VoLTE 已经启用并激活, 如果是 +QCFG: “ims”,1,0 就代表 VoLTE 启用了但没有激活, 如果是 +QCFG: “ims”,0,0 则代表 VoLTE 没有启用。
执行docker compose up -d 拉取镜像,并生成配置文件。可以通过 docker compose logs观察日志,没有报错的话,就可以进入下一步配置了。如果freepbx安装有报错,那么请删除asterisk文件夹,用上你的梯子,重新执行本流程。
配置软件
配置 freepbx
通过浏览器打开<a href="http://ip:1283">http://ip:1283</a> Ip+端口,访问freepbx的管理页面。跟着流程走,创建管理员账号。
创建完成后,用管理员账号进入管理员界面:
创建sip账号
首先,需要进入Connectivity -> Extensions,点击 Add Extension -> Add New SIP [chan_pjsip] Extension 按钮(位置在下图),添加一个 SIP 用户,这个用户用来接打电话。
然后进入用户添加界面,输入类似如下图的信息来添加 SIP 用户:
其中,User Extension 的数字是内部的分机号,也是 SIP 的登录用户名,你可以理解成企业电话系统里面的短号。Secret 是 SIP 密码,请务必记住这两个字段的信息,待会要用到。
创建拨号规则
然后来到 Connectivity -> Trunks,把模块添加进去,你有几个模块就需要添加几个 custom Trunks。配置如下图所示:
这个 Tab 要改的只有 Trunk Name,Maximum Channels 最好改成 1,然后还要修改 Dial String:
这里只有一个框,想都不用想就知道要改哪里。 里面写入类似 Quectel/quectel0/OUTNUM 的内容,中间的 quectel0 对应了你在配置文件里面配置的设备名字。
将设备添加完以后,需要进入 Connectivity -> Outbound Routes 添加 Outbound Routes。Route Name 是必要的,但可以设定成自己喜欢的值,毕竟它只是个名字。Route CID 代表的是内部的分机号,设置成上面设置的 10008。Trunk Sequence for Mached Routes 代表了使用哪个模块进行通话,这里选择一个喜欢的模块就行了,如果选择了两个或以上,那么后面的只有在前面的占线了才会使用。
接下来切到 Dial Patterns,设置一个 X. 作为 Pattern 就可以了,这代表匹配所有呼出的号码。
上图的规则,直接拨打号码、拨打号码添加+110前缀、+86前缀。都会通过ec20去拨打该号码。例如比sip软件上拨号18611665555或者+8610010或者+11010000都会被识别成通过4g模块拨号。
创建来电转发sip账号规则
最后,需要进入 Connectivity -> Inbound Routes,配置呼入电话转发给谁,这里 Description 写一个自己喜欢的,然后在最下面 Set Destination 选择 Extensions,然后会出现一个新的下拉框,在新的下拉框选择 10008 这个分机,这样就会把所有呼入转发给这个分机号。
配置sip的参数
进入Settings -> Asterisk SIP Settings
填写 External Address 地址。支持域名和IP。域名需要自行ddns配置解析。调试期间填你的局域网IP。
RTP Port Ranges 改成docker-compose.yaml里面的端口范围。这里是1000-10010.
去SIP Settings [chan_pjsip]里面开启udp、tcp的端口。也需要和docker-compose.yaml里面的对应。
设置完成后,点击右上角的 “Apply Config” 应用设置,然后便可以测试了。
测试
去下载个Zoiper就能测试了,至于具体用哪个sip客户端,就看你自己的选择了。
其他freepbx的配置,这里就不多说了,那得你根据自己的情况去问问gpt或者google了
这里主要是介绍通过docker运行asterisk + freepbx + asterisk-chan-quectel 罢了。将这些东西docker化。









微信扫一扫,打赏作者吧~