
简介Asterisk作为开源PBX电话系统的代表性方案在中小型企业通信与VoIP开发中应用广泛。这份PDF指南面向需要搭建或维护电话系统的运维人员与通信开发者从系统依赖套件安装、源码下载到zaptel、libpri与Asterisk的编译部署给出完整操作流程同时覆盖SIP分机配置、extensions.conf拨号规则、远端管理账号配置及telnet登录等关键环节并针对分机参数逐项说明。包内为1个PDF文档体积约90KB内容精炼便于查阅。作者结合实操案例整理了配置示例与注释读者可依据文档快速完成Asterisk基础环境的搭建与基本呼叫测试减少踩坑适合初次接触PBX系统的学习者作为入门参考。目前已有100人学习/下载是一份轻量实用的Asterisk实战笔记。 凌晨三点告警群弹出“分机全部掉线”上去看 asterisk 进程还活着但 SIP 注册全部超时。这种事故十有八九不是网络问题而是安装阶段少了一个 Jansson 依赖Asterisk 的模块加载器不会在启动时把所有符号一次性验证完服务能启动不代表通道可用。自建 PBX 的第一道坎通常就压在 asterisk 安装与配置这条路径上它决定了后面每一个分机、每一条路由是否稳定。这篇按我实际会做的顺序把依赖、configure、menuselect、pjsip.conf、extensions.conf 到验证排障整条链路讲清楚适合正在把一台 Linux 机器变成电话交换机的运维、做呼叫中心或语音机器人接入的开发以及想把手头老式 PBX 迁到开源方案的工程师。2. 从源码安装 Asterisk依赖、configure 与 menuselect 的取舍2.1 为什么不做 yum install asterisk发行版仓库里通常有 asterisk 包装起来快但我不建议生产环境直接用。仓库包普遍落后主线好几个大版本部分模块被裁剪过文件布局和官方 systemd 单元也不完全一致。更麻烦的是仓库里的 PJSIP 栈往往是单独打包的版本与主程序对不上时会出现“模块加载失败但服务进程正常”的状态日志要到很靠后的位置才能看到 ERROR反而更难排查。如果你打算长期维护直接下载官方 LTS 源码包编译。源码安装在依赖管理上更明确缺了哪个-devel包configure 阶段就会报出来不会把问题拖到运行期。以下步骤基于官方源码目录结构以/usr/src为工作目录。2.2 安装依赖CentOS/RHEL 与 Debian 两套命令先装编译工具链和最关键的运行库头文件。RHEL/CentOS 系含 7 系用下面这组sudo yum install -y epel-release sudo groupinstall -y Development Tools sudo yum install -y wget libxml2-devel libsqlite3-devel ncurses-devel \ uuid-devel openssl-devel libedit-devel libjansson-develDebian/Ubuntu 系把包名换成-devsudo apt update sudo apt install -y build-essential wget libxml2-dev libsqlite3-dev \ libncurses-dev uuid-dev libssl-dev libedit-dev libjansson-dev逐项说明一下为什么是这些包libxml2负责解析一部分功能模块的 XML 配置缺了编译能过但部分 app 模块用不了sqlite3是 CDR 通话记录和内置数据库的后端jansson是 JSON 解析库res_pjsip 的配置和消息处理直接依赖它很多“装完注册不上”的怪问题都是这里缺头文件导致 PJSIP 被悄悄跳过libedit给asterisk -r控制台提供历史命令功能不装也能进控制台但体验很差。2.3 configure 参数里值得调的两个 bundled解压源码包后核心配置就一步tar xf asterisk-*.tar.gz cd asterisk-*/ ./configure --with-jansson-bundled --with-pjproject-bundledconfigure 会打印一份 summary重点看最下方有没有出现jansson、libedit、sqlite3相关的FOUND状态。出现NOT FOUND就回去补依赖不要用--without-*强行绕过。--with-jansson-bundled和--with-pjproject-bundled是我在陌生机器上必加的两个参数。意思是编译时把 jansson 和 PJProject 源码一并编译而不是找系统版本。PJSIP 栈对这两个库的符号版本很敏感系统库太新或太旧都会导致运行时异常用 bundled 版本可以锁死行为减少“configure 通过、编译报错、启动异常”这类链路问题。2.4 menuselect选模块而不是全选接着作模块选择make menuselect这个命令打开 ncurses 交互界面功能是用菜单方式生成menuselect.makeopts。我在菜单里必看四处Channel Drivers确认chan_pjsip被选中旧的chan_sip理论上仍然可用但新配置一律走 PJSIP不要在这里两个都开着。Resource Modulesres_pjsip、res_rtp_asterisk必须保留。Applications按需勾选app_dial、app_queue、app_voicemail、app_playback。如果后面要接队列客服app_queue不要漏。Formatters至少保留format_wav和format_alaw录音和回放都会用到。纯命令行环境拉不起交互界面时可以用非交互方式调整make menuselect.makeopts make menuselect --disable channel_chan_sip --enable app_queue这种写法的行为是直接修改menuselect.makeopts对chan_sip这类已经默认启用的模块用--disable关闭即可。2.5 make install、samples、config 一步到位模块选完就进入编译安装make -j$(nproc) sudo make install sudo make samples sudo make config sudo ldconfig编译用时取决于机器核数4 核机器一般 15 到 40 分钟。如果你执行make -j$(nproc)时报内存不足把并行度降到-j2。make config会生成 systemd 的 service 文件装完直接sudo systemctl enable --now asterisk sudo systemctl status asterisk asterisk -Vasterisk -V输出版本号即代表安装成功。make samples会生成一份带注释的示例配置新手靠它能快速理解格式但其中的sip.conf、extensions.conf等是示例值生产环境应逐项覆盖不要直接复用。提示make samples生成的目录权限是 root如果你后面用asterisk -rx改配置注意用户和文件属主建议统一chown -R asterisk:asterisk /etc/asterisk。3. PJSIP 分机注册配置endpoint、auth、aor 三个对象先建立模型3.1 从 chan_sip 到 res_pjsip为什么现在写 pjsip.conf老教程里大量出现sip.conf和sip show peers那是 chan_sip 时代的写法。chan_sip 在维护上已经停摆现代 LTS 版本的主线 SIP 栈是res_pjsip配置文件是/etc/asterisk/pjsip.conf控制台命令是pjsip show ...。PJSIP 的配置模型比 chan_sip 复杂在对象必须分离endpoint 描述“这个人是谁”、auth 描述“他拿什么密码验证”、aor 描述“他注册到哪、允许几个注册”。这三个概念对应到网页、手机软电话和实体话机时是一致的先理解了再写配置不容易出错。3.2 一个最小 pjsip.conf 示例下面这个例子足够让一个软电话注册成 1001。写到/etc/asterisk/pjsip.conf[transport-udp] type transport protocol udp bind 0.0.0.0:5060 [1001] type endpoint context internal disallow all allow ulaw,alaw auth 1001-auth aors 1001-aor [1001-auth] type auth auth_type userpass username 1001 password Zzz2024 [1001-aor] type aor max_contacts 1 qualify_frequency 30配置文件的逻辑是transport 定义监听地址endpoint 通过auth和aors两个字段分别指向认证配置和联系地址配置。话机发起 REGISTER 时Asterisk 先按aors说的地方找 address of record再用auth里的用户名密码做 digest 认证。disallow all后再allow ulaw,alaw是必写的组合习惯先清空全部编解码再按优先级打开需要的否则通话双方会协商出系统默认的乱序编码。qualify_frequency 30表示每 30 秒发一次 OPTIONS 消息探测分机在线状态在控制台pjsip show contacts里就能看到每个分机是Avail还是Unavail。3.3 注册流程和参数401 挑战到底发生了什么如果你抓 SIP 包会看到完整流程话机发 REGISTERAsterisk 回复401 Unauthorized并带上 nonce话机用密码和 nonce 计算 digest 后重发 REGISTER服务端验证通过返回200 OK随后话机把 contact 注册到 AOR。所以配置完不要只看“注册失败”先看消息里是 401 之后没有第二次请求还是第二次请求被 403 拒绝。前者通常是认证配置没生效后者通常是密码不对或账号不存在。3.4 三个常用参数的推荐值参数位置推荐值说明contextendpointinternal / callcenter决定分机呼入后进入哪个拨号计划上下文写错会导致“注册成功但拨不出去”max_contactsaor1只允许一台设备注册软电话与实体话机同时用同一分机时应设为 2 并配合remove_existingqualify_frequencyaor30探测间隔秒数过小会增加信令量过大会让在线状态迟钝calleridendpoint销售部 1001分机外显名称不设置时只有号码常见误用是把context写到 auth 里。auth 只负责认证不管呼叫走向呼叫走向由 endpoint 上的context决定。另一个常见错误是一个大括号写多个 type 段注意 pjsip.conf 中同名段会合并但不同 type 之间是并列关系别把type endpoint和type auth写进同一个[1001]段那样配置解析会直接失败。4. extensions.conf 编写让一个呼叫完整走完生命周期4.1 从“呼叫 1002”看 Dial 的执行过程分机能注册之后拨号计划决定呼叫去哪。/etc/asterisk/extensions.conf里先建一个最小上下文[internal] exten _1XXX,1,NoOp(内部呼叫 ${EXTEN}) same n,Dial(PJSIP/${EXTEN},30) same n,Playback(ss-noservice) same n,Hangup()上面的_1XXX是模式匹配下划线表示这是一条表达式1XXX匹配 1001 到 1999 任意号码。${EXTEN}是实际拨出的号码Dial(PJSIP/${EXTEN},30)表示通过 PJSIP 通道呼叫对应分机30 秒无应答则继续执行下一步。Dial 之后的几行是失败处理Playback(ss-noservice)播放“无法接通”的语音Hangup()挂断。这里使用same n延续上一优先级整段逻辑清晰比手写递增数字优先级好维护。Dial 过程中遇到对方占线时默认会收到忙音并结束呼叫不需要额外配置如果你希望占线也进入备用语音提示需要给 Dial 加第三个参数区分状态。4.2 用 DIALSTATUS 做分支占线、超时、接通后的差异化处理Dial 结束后 Asterisk 会把结果写入DIALSTATUS常见值是ANSWER、BUSY、NOANSWER、CANCEL。在拨号计划里按状态跳转是常用做法[internal] exten _1XXX,1,Dial(PJSIP/${EXTEN},30) same n,GotoIf($[${DIALSTATUS} ANSWER]?ok:fail) same n(fail),Playback(ss-noanswer) same n,Hangup() same n(ok),Hangup()GotoIf的作用是取DIALSTATUS和字符串ANSWER做比较满足则跳转到ok标签否则顺序进入fail标签。标签用标签名:写在优先级后定义注意ok标签位置在Hangup()之后但 Goto 是跳转执行不受位置影响。BUSY、NOANSWER在实际项目中处理方式不同占线可以播放busy提示超时可以转语音信箱。通过多个 GotoIf 级联判断或者改用Dial的第三个参数写D(alreadybusy)都能实现建议先用上面的单分支版本把流程跑通再扩张逻辑。4.3 接到队列简单客服场景的 Queue 编排把来话接入队列是 Asterisk 最常见的生产场景之一。假设市场部要一个排队组先把app_queue勾进模块编译前面 menuselect 已提到然后写两个文件; queues.conf [marketing] musicclass default strategy ringall timeout 20 member PJSIP/1001 member PJSIP/1002; extensions.conf [callcenter] exten s,1,Queue(marketing) same n,Hangup()strategy ringall表示所有客服同时振铃接起一个其他人停止振铃换成leastrecent则优先呼叫最近最少接听的坐席。timeout20是单成员振铃 20 秒无人接则继续下一策略。队列的排队长尾参数还包括wrapuptime挂机后休息时间和maxlen最大排队人数在压测前建议都调成短值观察运行状态。提示Queues 状态内存中维护修改 queues.conf 后不需要重启执行module reload app_queue.so即可长时间运行后用queue show marketing查看成员实时状态。4.4 配置落地与重载顺序改完两个配置文件用控制台命令重载sudo asterisk -rx dialplan reload sudo asterisk -rx module reload res_pjsip.so sudo asterisk -rx module reload app_queue.soasterisk -rx 命令等价于进入asterisk -r后交互执行命令适合脚本调用。重载顺序建议先拨号计划后模块因为队列模块加载时可能引用拨号计划里的 context。重载后立刻能验证用两个软电话分机互拨能听到回铃音并接通这步就过去了。5. 启动验证与 RTP 排障从控制台到抓包5.1 四个命令确认安装配置正常装完并配置后进控制台看状态sudo asterisk -rvvvv pjsip show endpoints pjsip show contacts core show uptimepjsip show endpoints列出所有 endpoint 配置及当前状态pjsip show contacts能看到每个 AOR 下实际注册的设备Contact一列出现sip:1001192.168.x.x:xxxxx就说明注册链路通了。-vvvv是控制台 verbosity 等级数字越大打印越细日常用-r即可别长期开着高等级刷屏。5.2 一接通就断先查编解码与会话计时器注册正常但一接通就断最常见的两类原因。第一类是编解码协商不一致控制台执行rtp set debug on后拨一个测试电话看输出里 RTP 包是否双向到达看不到对端 RTP 一般都和防火墙有关Asterisk 的 RTP 默认端口段在/etc/asterisk/rtp.conf的rtpstart和rtpend通常是 10000 到 20000UDP 端口段需要在防火墙放行。第二类是 SIP 会话计时器部分软电话默认开启 session-timersAsterisk 如果在几个周期内没收到刷新请求会主动拆线临时确认时可以置session-timersaccept观察是否稳定。看完这四点Asterisk 的安装与配置链路基本就闭环了编译依赖、模块选择、PJSIP 注册、拨号计划路由、RTP 排障。把pjsip show contacts和rtp set debug on这两个命令背下来生产环境一半以上的通信问题都靠它们定位。本文还有配套的精品资源点击获取