三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

CentOS 7上从零部署Asterisk SIP服务器:编译配置与实战指南

CentOS 7上从零部署Asterisk SIP服务器:编译配置与实战指南

1. 项目概述:为什么选择Asterisk搭建SIP服务器?

如果你正在寻找一个稳定、灵活且功能强大的开源电话系统解决方案,那么Asterisk几乎是一个绕不开的名字。它不仅仅是一个软交换,更像是一个通信领域的“瑞士军刀”,能够处理语音、视频、文字等各种通信协议。这次我们要做的,就是在经典的CentOS 7系统上,从零开始安装和部署Asterisk,搭建一个属于自己的SIP服务器。无论是想学习VoIP技术、搭建企业内部电话系统,还是为开发测试提供一个通信环境,这个项目都是一个非常扎实的起点。CentOS 7虽然已停止主流维护,但其极高的稳定性和广泛的企业应用基础,使得它依然是许多传统服务和学习环境的首选。整个过程会涉及到系统准备、源码编译、基础配置和功能测试几个核心环节,我会把每一步的原理和踩过的坑都讲清楚。

2. 前期准备:系统环境与依赖梳理

在动手编译安装之前,打好基础是关键。一个干净、准备充分的系统环境能避免后续无数稀奇古怪的错误。

2.1 操作系统初始化配置

首先,确保你的CentOS 7系统是最小化安装的,这能保证环境干净。登录系统后,第一件事就是更新系统并安装必要的编译工具链。

# 更新系统到最新状态 sudo yum update -y # 安装开发工具组,它包含了gcc, make, autoconf等编译必需品 sudo yum groupinstall -y "Development Tools" # 安装Wget,用于下载源码包 sudo yum install -y wget

接下来,我们需要处理CentOS 7默认的防火墙和SELinux,它们常常是网络服务的“拦路虎”。对于实验环境,我们可以先暂时调整它们以减少复杂度。

# 停止并禁用firewalld(生产环境请谨慎,应配置具体规则) sudo systemctl stop firewalld sudo systemctl disable firewalld # 将SELinux设置为宽容模式,避免权限问题阻塞Asterisk运行 sudo setenforce 0 # 为了使重启后依然生效,需要修改配置文件 sudo sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

注意:在生产环境中,直接关闭防火墙和SELinux是极不安全的做法。这里仅为了简化实验流程。正确的做法是学习并配置firewalld规则,开放SIP(5060端口)和RTP(10000-20000端口范围)流量,并将SELinux策略调整为允许Asterisk相关操作。

2.2 安装Asterisk核心依赖库

Asterisk的功能模块依赖于许多第三方库。我们需要一次性把它们装齐。这些库主要分为几类:音频编解码支持(如libogg, libvorbis)、SSL/TLS加密支持、数据库支持(用于存储配置或通话记录)以及XML解析支持等。

# 安装核心依赖库 sudo yum install -y epel-release sudo yum install -y libedit-devel libxml2-devel sqlite-devel openssl-devel sudo yum install -y ncurses-devel libuuid-devel libjansson-devel sudo yum install -y libsrtp libsrtp-devel sudo yum install -y pkgconfig # 安装音频编解码相关库 sudo yum install -y libogg-devel libvorbis-devel speex-devel speexdsp-devel sudo yum install -y libcurl-devel libical-devel neon-devel sudo yum install -y libresample-devel libsndfile-devel

如果遇到某些包在默认仓库找不到,可以尝试启用EPEL(Extra Packages for Enterprise Linux)仓库,正如上面命令所做。安装完依赖后,建议重启一次系统,确保所有环境变更生效。

3. 编译与安装Asterisk

与直接使用包管理器安装相比,源码编译能让我们获得最新的版本,并对功能模块进行定制化选择。这是最推荐的方式。

3.1 下载与解压源码

我们前往Asterisk官网下载最新的LTS(长期支持)版本源码包。通常,LTS版本更稳定,适合用于生产或学习。

# 创建一个专用的源码目录 cd /usr/src # 下载Asterisk源码包(请替换为官网最新的LTS版本链接) sudo wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-20-current.tar.gz # 解压源码包 sudo tar -zxvf asterisk-20-current.tar.gz # 进入解压后的目录 cd asterisk-20.*

3.2 运行配置与编译脚本

Asterisk提供了强大的配置脚本,可以检查系统环境并让我们选择需要编译的模块。

# 运行configure脚本,进行编译前配置 sudo ./configure

运行./configure后,终端会输出大量的检查信息。你需要仔细阅读最后部分的摘要,它会以“configure menuselect”结尾。这时,我们可以启动一个菜单驱动的模块选择界面。

# 启动模块选择界面 sudo make menuselect

menuselect界面中,你可以使用方向键导航,空格键选中或取消选中模块。对于初学者,一个实用的建议是:

  1. Core Sound Packages中,确保你的国家或地区的声音提示包被选中(例如,EN代表英语)。
  2. Channel Drivers中,确保chan_sip被选中。虽然Asterisk推荐使用更新的chan_pjsip,但chan_sip更简单直观,适合入门。
  3. 其他模块可以保持默认。确认后,按F12保存并退出。

接下来,开始漫长的编译过程。make命令会调用编译器,将源代码转换为可执行文件。

# 开始编译,-j参数可以指定并行编译的作业数,以加快速度(如4核CPU可用-j4) sudo make -j4

编译过程可能需要10-30分钟,取决于服务器性能。如果中途没有报错,就可以进行安装了。

# 安装编译好的Asterisk及其模块 sudo make install # 安装基本的配置文件样本 sudo make samples # 安装初始化脚本和日志轮转配置 sudo make config

3.3 创建Asterisk运行用户并设置权限

为了安全,我们不建议以root身份直接运行Asterisk。需要创建一个专用的系统用户和组。

# 添加asterisk用户和组 sudo groupadd asterisk sudo useradd -r -d /var/lib/asterisk -g asterisk asterisk # 将Asterisk相关目录的所有权更改给asterisk用户 sudo chown -R asterisk:asterisk /etc/asterisk sudo chown -R asterisk:asterisk /var/lib/asterisk sudo chown -R asterisk:asterisk /var/log/asterisk sudo chown -R asterisk:asterisk /var/spool/asterisk sudo chown -R asterisk:asterisk /usr/lib64/asterisk

4. 核心配置文件解析与基础SIP设置

安装完成后,/etc/asterisk目录下存放了所有配置文件。我们需要重点配置其中几个,才能让SIP服务器跑起来。

4.1 配置SIP通道文件 (sip.conf)

sip.conf文件定义了SIP用户(分机)、认证方式和网络监听设置。我们先备份原始样本文件,然后编辑。

sudo cp /etc/asterisk/sip.conf /etc/asterisk/sip.conf.bak sudo vim /etc/asterisk/sip.conf

一个最简化的[general]段和两个分机配置示例如下:

[general] context=public bindaddr=0.0.0.0 bindport=5060 ; 允许的音频编码,alaw和ulaw是G.711标准,兼容性最好 disallow=all allow=ulaw allow=alaw ; 定义第一个SIP分机 (分机号1001) [1001] type=friend secret=123456 host=dynamic context=internal dtmfmode=rfc2833 ; 定义第二个SIP分机 (分机号1002) [1002] type=friend secret=654321 host=dynamic context=internal dtmfmode=rfc2833

关键参数解析

  • context:上下文,是拨号计划中重要的路由标签。[general]里的context是默认上下文,分机中的context定义了该分机发起的呼叫进入拨号计划的哪个部分。
  • bindaddr=0.0.0.0:监听所有网络接口。如果服务器有多个IP,可以指定其中一个。
  • type=friend:结合了user(接收呼叫)和peer(发起呼叫)的特性,最常用。
  • secret:分机的注册密码。
  • host=dynamic:允许该分机从任意IP地址注册。如果设为固定IP,则只能从该IP注册。

4.2 配置拨号计划文件 (extensions.conf)

拨号计划是Asterisk的“大脑”,它决定了来电该如何处理。比如,分机1001拨打1002,该怎样接通。

sudo cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.bak sudo vim /etc/asterisk/extensions.conf

我们编辑[internal]上下文,这是上面分机配置中指定的。

[internal] ; 分机1001和1002互相拨打 exten => 1001,1,Dial(SIP/1001,20) exten => 1001,n,Hangup() exten => 1002,1,Dial(SIP/1002,20) exten => 1002,n,Hangup() ; 一个简单的语音菜单示例(IVR) exten => 888,1,Answer() exten => 888,n,Background(hello-world) exten => 888,n,Hangup()

拨号计划语法解释

  • exten =>:定义一个分机或扩展。
  • 1001:匹配的号码。
  • 1:优先级,按顺序执行。
  • Dial(SIP/1002,20):应用Dial程序,尝试呼叫SIP通道的1002分机,超时20秒。
  • n:代表“下一个优先级”,即顺序执行。

4.3 配置模块加载文件 (modules.conf)

这个文件控制Asterisk启动时加载哪些模块。初期我们可以让它自动加载。

sudo vim /etc/asterisk/modules.conf

确保有以下内容(通常样本文件已配置好):

[modules] autoload=yes

5. 启动Asterisk与服务验证

配置完成后,就可以启动服务并进行测试了。

5.1 启动服务并设置开机自启

# 使用systemctl启动Asterisk服务 sudo systemctl start asterisk # 设置开机自动启动 sudo systemctl enable asterisk # 检查服务状态,确认运行正常 sudo systemctl status asterisk

如果状态显示为active (running),说明服务已成功启动。

5.2 使用Asterisk CLI进行管理

Asterisk提供了一个强大的命令行交互界面(CLI),用于监控和管理。

# 连接到Asterisk CLI sudo asterisk -rvvv

连接成功后,提示符会变成*CLI>。你可以在这里运行各种命令:

  • sip show peers:查看所有配置的SIP对等端(分机)及其注册状态。
  • core show channels:查看当前活跃的通话通道。
  • dialplan show:显示加载的拨号计划。
  • reload:重新加载配置文件(修改配置后常用)。

5.3 使用软电话客户端测试

现在,你需要在同一网络内的另一台电脑或手机上安装SIP软电话客户端(如MicroSIP for Windows, Linphone, Zoiper等)。以MicroSIP为例,添加一个账户:

  • 服务器地址:你的CentOS服务器的IP地址。
  • 用户名/分机号:1001
  • 密码:123456
  • 域名:(通常与服务器地址相同或留空)

点击注册(Register),如果状态显示“Registered”,恭喜你,注册成功了!用同样的方法配置分机1002。然后尝试用1001拨打1002,你应该能听到回铃音并在另一台设备上看到来电,接听后即可进行通话。

6. 进阶配置与功能探索

基础通话实现后,你可以探索更多功能,让这个SIP服务器变得更实用。

6.1 配置音乐保持(MoH)

当通话被保持时,播放背景音乐是一个专业功能。首先,你需要将音乐文件(格式如WAV,编码为ulaw/alaw)放入指定目录。

# 创建音乐保持目录 sudo mkdir -p /var/lib/asterisk/moh # 将你的音乐文件拷贝至此,例如 custom.wav # 然后修改配置文件 sudo vim /etc/asterisk/musiconhold.conf

添加一个分类:

[default] mode=files directory=/var/lib/asterisk/moh

sip.conf的分机配置中,可以设置musiconhold=default。在拨号计划中,使用Set(CHANNEL(musicclass)=default)来应用。

6.2 实现外线拨打(Trunking)

要让内部分机能拨打外部电话(如手机或固话),你需要配置一个SIP中继(Trunk)。这通常需要向VoIP服务商购买服务并获得他们的服务器地址、用户名和密码。

sip.conf中添加一个新的[trunk]段:

[voipms-trunk] type=peer host=sip.voip.ms defaultuser=your_username secret=your_password fromuser=your_username fromdomain=sip.voip.ms context=from-trunk insecure=invite,port

然后在extensions.conf中,创建一个新的上下文(例如outbound)来处理出局呼叫,并在[internal]上下文中添加规则,将特定前缀(如拨9)的呼叫路由到外线。

[internal] ; ... 其他规则 ... exten => _9X.,1,Dial(SIP/voipms-trunk/${EXTEN:1}) exten => _9X.,n,Hangup() [outbound] ; 这里可以定义更复杂的外呼规则

6.3 启用通话录音

Asterisk可以轻松实现通话录音。在拨号计划中,使用MixMonitor应用程序。

exten => 1001,1,Dial(SIP/1001,20) ; 在Dial之后,开始录音。${UNIQUEID}是通话的唯一ID,用作文件名。 exten => 1001,n,MixMonitor(${UNIQUEID}.wav) exten => 1001,n,Hangup()

录音文件默认会保存在/var/spool/asterisk/monitor/目录下。你需要确保该目录对asterisk用户有写权限。

7. 常见问题排查与性能调优实录

在实际部署中,你几乎一定会遇到一些问题。这里记录了几个最典型的案例和解决思路。

7.1 分机无法注册

这是最常见的问题。请按以下清单排查:

  1. 网络连通性:在客户端使用pingtelnet <服务器IP> 5060检查是否能连接到服务器的5060端口。
  2. 防火墙:确认服务器本地防火墙(即使firewalld已停用,也可能有iptables规则)和任何中间网络设备(如路由器)没有阻止UDP 5060端口以及RTP端口范围(默认为10000-20000)。
  3. 配置错误:仔细检查sip.conf中的分机号、密码、hostcontext是否与客户端配置完全一致。一个多余的空格都可能导致失败。
  4. SELinux:如果SELinux处于强制模式,可能会阻止Asterisk绑定端口或访问文件。查看/var/log/audit/audit.log获取线索,或暂时设置为宽容模式进行测试。
  5. 查看日志:Asterisk的详细日志是解决问题的金钥匙。在CLI中运行sip set debug on然后尝试注册,CLI会输出详细的SIP信令交互过程。同时,查看/var/log/asterisk/messages/var/log/asterisk/full文件。

7.2 能注册但无法通话(无声音)

通常表现为能振铃、能接听,但双方听不到声音。这几乎都是RTP(实时传输协议)流的问题,即音频数据流无法互通。

  1. NAT问题:如果客户端位于路由器后面(有NAT),而服务器在公网或不同子网,Asterisk需要知道客户端的真实公网IP和端口来发送RTP。在sip.conf[general]段或分机段中,尝试添加nat=yesnat=force_rport
  2. RTP端口范围:确保防火墙开放了RTP端口(默认10000-20000/UDP)。在rtp.conf中可以修改这个范围。
  3. 编码协商失败:检查sip.conf中的disallowallow设置,确保双方至少有一种共同的编码(如ulawalaw)。在CLI中使用core show translation查看编码转换路径是否建立。
  4. ICE/STUN/TURN:在复杂的NAT环境下(如对称型NAT),可能需要配置STUN服务器或使用ICE。这属于高级话题,初期可先通过设置natexternip参数尝试解决。

7.3 系统性能与稳定性调优

当分机数量增多或通话量变大时,一些基础调优能提升稳定性。

  1. 文件描述符限制:Asterisk每个连接都会消耗文件描述符。编辑/etc/security/limits.conf,为asterisk用户增加限制。
    asterisk soft nofile 65536 asterisk hard nofile 65536
  2. 调整RTP设置:编辑/etc/asterisk/rtp.conf,可以调整RTP包的尺寸、超时时间,并可以缩小端口范围以减少防火墙压力(如rtpstart=10000rtpend=10100)。
  3. 日志级别管理:默认的详细日志会占用大量磁盘IO。在生产环境中,应降低日志级别。在logger.conf中,将verbosedebug调低,甚至关闭。
  4. 定期清理:设置一个定时任务(cron job),定期清理旧的录音文件、通话记录(CDR)和核心转储文件,防止磁盘被占满。

7.4 从 chan_sip 迁移到 chan_pjsip

Asterisk社区早已推荐使用更现代、功能更强大的chan_pjsip替代传统的chan_sipchan_pjsip配置更模块化(分为端点、认证、路由等),支持更丰富的RFC标准。迁移并不复杂,但需要重写配置。主要配置文件从单一的sip.conf变为pjsip.confpjsip_wizard.conf等。对于新项目,建议直接从chan_pjsip开始学习。

← 返回列表