简介:面向网络工程师与VoIP运维人员的技术文档,介绍采用SIP协议的Cisco IOS语音网关在企业IP通信中的角色与部署要点。内容涵盖PSTN与IP网络之间的信令转换、SIP中继、PBX互联,以及QoS、呼叫准入控制、会话边界控制器、应急故障切换等关键特性,并对Cisco 1700/2600/2800/3700/3800等系列路由器的语音接口配置做了说明。资源为1个doc文档,压缩包约71KB,适合需要快速掌握思科语音网关SIP方案原理与选型思路的读者。已有275人学习下载,文档结构完整,包含支持的标准RFC列表与平台对比信息,可作为日常排错和网络设计时的参考。
1. 采用SIP协议的Cisco IOS语音网关,到底要解决什么问题
去年帮一家制造企业替换老旧的PRI中继,客户说得很直接:分机从办公室打到手机上,经常听到运营商割接通知,E1板上还时不时亮红灯。我建议他们不用再买独立语音网关,就在已有的Cisco ISR路由器上开一个SIP语音网关能力,把运营商IMS直接接进路由器。采用SIP协议的Cisco IOS语音网关,说到底就是把原来跑在TDM链路和硬件语音板卡上的活儿,搬到路由器上用一个IP信令协议完成:注册、呼叫路由、号码变换、编解码协商全部走SIP,网关不再关心物理E1在哪块板上。
这东西适合两类人:一类是手里有存量Cisco路由器、不想再添硬件的中小企业IT;另一类是刚接手UC项目的工程师,需要快速理解dial-peer、voice service、sip-ua这些概念到底怎么协同。反直觉的一点是,很多人以为SIP网关就是把PRI换成IP地址,其实配置层面要动的是三个配置域,坑也大多出在“路由配置了但UA行为没配置”。
2. 先把SIP网关的三个配置域分清楚:voice service、dial-peer与sip-ua
2.1 三个配置域各自的职责边界
我见过太多人拿到Cisco IOS SIP网关配置就到处找“SIP配置”在哪一段,然后发现命令散落在三个地方。这不是设计混乱,而是Cisco把语音网关的职责切成了三层,每一层处理不同的问题。
第一层是voice service voip,它定义网关整体的VoIP行为。这里配置的是“网关允不允许SIP到SIP的呼叫转接”、“SIP绑定在哪个源接口上”、“要不要透传remote-party-id”这类全局策略。你可以把它理解成总开关和总闸。voice service voip下的sip子模式,控制SIP协议本身的行为,比如是否允许tcp、会话定时器、SIP OPTIONS keepalive。
第二层是dial-peer,它负责呼叫路由。每个dial-peer定义了一条“匹配规则+目标”的组合,有点像静态路由。所谓呼叫路由,就是网关收到一个呼叫请求时,根据被叫号码、主叫号码或者入向中继名,把一个呼叫交给正确的出口。没有dial-peer匹配,网关再聪明也不会把呼叫送出去。
第三层是sip-ua,它管理网关作为SIP用户代理的“作息表”。要不要向某个SIP服务器注册、注册过期时间多久、用什么用户名和密码做鉴权、SIP会话的定时器数值,都在这里定义。它和dial-peer最大的区别是:dial-peer管“呼叫往哪走”,sip-ua管“网关以什么身份对外说话”。
这三个配置域不是按顺序执行的,而是协同工作的。我一般这样记忆:voice service voip是宪法,dial-peer是路由表,sip-ua是身份证明。
2.2 注册模式与中继模式:什么时候把网关当UA,什么时候当背靠背代理
配置SIP网关前必须先回答一个问题:这个网关在对端眼里是什么角色。Cisco IOS语音网关在SIP世界里可以当两种角色,搞混了会让后面所有dial-peer白配。
第一种是注册模式。网关作为SIP UA,主动向IP-PBX或运营商IMS发起REGISTER请求,拿到一个AOR(Address of Record)地址。企业分支的语音网关对接总部CUCM或运营商IMS时,最常用这种模式。网关自己维护注册状态,过期了要重新注册,对端通过注册表查到网关的位置。
第二种是中继模式,也叫背靠背模式。网关不注册,而是作为SIP中继的端点,对端通过IP地址直连呼叫过来。这种模式常见于两个企业通过专线点对点对接,或者运营商给你一个固定的SIP中继IP而不用注册账号。
选哪种,直接决定配置写法。注册模式下,sip-ua段必须配置registrar和鉴权信息,不配就等着对端一直回401;中继模式下,dial-peer里的session target直接指向对方IP,不需要注册,但需要确认SIP消息里的host部分能被对端识别。
2.3 一份最小SIP网关配置骨架:先让它能注册、能路由
下面是一份最小可用配置骨架,覆盖了“注册到IMS/运营商 + 分机呼叫路由”的经典场景。我以IOS 15.x以上的语法为例,新版本命令依然兼容:
voice service voip allow-connections sip to sip sip bind control source-interface Loopback0 bind media source-interface Loopback0 ! voice class codec 1 codec preference 1 g711ulaw codec preference 2 g729r8 ! dial-peer voice 100 voip description Outbound to IMS session protocol sipv2 session target ipv4:10.1.1.2:5060 voice-class codec 1 dtmf-relay rtp-nte destination-pattern 9T ! sip-ua credentials username 8613912345678 password 0 Cisc0@IMS authentication username 8613912345678 password 0 Cisc0@IMS registrar 10.1.1.2:5060 expires 3600 !这段配置里,allow-connections sip to sip允许SIP端口之间的呼叫转接,这是很多老版本网关转接失败的原因,新配置里建议直接加上。bind control和bind media把信令和媒体都绑到Loopback0,避免多WAN口场景下RTP端口从错误的接口出去。voice class codec 1定义了编解码优先级,G.711优先、G.729兜底,运营商如果只支持G.711,协商时会自动选到第一项。
dial-peer voice 100 voip是出向呼叫的匹配规则,destination-pattern 9T表示所有以9开头的号码都走这个中继出局,session target指向运营商IMS的IP。sip-ua里credentials和authentication是一对,用户名用运营商的SIP账号,密码用明文0或者密文7,registrar指定注册服务器并设置3600秒过期。
这份配置虽然短,但已经能完成“注册 + 拨打外线”两个核心动作。真实环境里还需要加号码变换、入向dial-peer和编解码约束,这些在第3章展开。
3. 从零配出一台可用的Cisco IOS SIP网关:dial-peer配对与呼叫路由
3.1 成对配置inbound与outbound dial-peer:先想清楚呼叫从哪来、到哪去
dial-peer是Cisco IOS语音网关最核心的路由概念,但新手常犯的错是只配出向、不配入向,结果外线能打出去、分机收不到来电。实际上每一次呼叫都需要两个dial-peer配合:一个负责接住入向呼叫,一个负责把呼叫送出去。
来看一个典型场景:运营商的PSTN用户拨打你公司总机010-12345678,呼叫从IMS进到网关。网关需要有一个入向dial-peer匹配这个被叫号码,把它路由到内部分机501。配置如下:
dial-peer voice 200 voip description Inbound from IMS to extension session protocol sipv2 incoming called-number 01012345678 voice-class codec 1 dtmf-relay rtp-nte direct-inward-dial ! dial-peer voice 201 pots description Local extension 501 destination-pattern 501 port 0/0/0 !incoming called-number 01012345678让这个dial-peer只匹配被叫为总机号码的SIP INVITE。direct-inward-dial允许呼叫直接到达分机而不经过自动话务员,这是企业总机最常见的需求。dial-peer voice 201 pots则把号码501映射到本地模拟分机端口0/0/0上。
两个dial-peer共同完成一次入向呼叫的完整路由。理解它们如何配对,建议记住一条规则:入向dial-peer决定“谁接住这个呼叫”,出向dial-peer决定“下一步往哪里送”。在实际排障时,先用show dial-peer voice summary看每个dial-peer的匹配情况,比直接看SIP消息更快定位是路由问题还是协议问题。
3.2 在sip-ua下完成注册与鉴权:registrar、credentials与authentication怎么配合
很多工程师配置dial-peer能拨号,但一接运营商就注册失败,问题几乎都出在sip-ua配置不完整。尤其常见的是只配了registrar但没配credentials,或者credentials和authentication的用户名不一致,导致REGISTER请求被运营商回401后没有带正确的Authorization头重发。
sip-ua段可以理解成网关的SIP账号管理界面。下面的配置是一个我常用的完整注册模板:
sip-ua credentials username 8613912345678 password 7 094F0A2B1C3D authentication username 8613912345678 password 7 094F0A2B1C3D registrar 10.1.1.2:5060 expires 3600 sessions max 200 timers register 60 !credentials用于在REGISTER请求中携带账号信息,authentication用于响应401挑战时生成摘要。有些运营商只要求其中一个,但建议两个都保持一致。registrar后面的expires 3600是注册过期时间,运营商一般要求300到3600秒,配太短会导致REGISTER流量频繁,配太长运营商可能主动踢掉注册。timers register 60设置注册失败后的重试间隔,网络抖动时这个参数能救命,默认值有时候会到几分钟,改成60秒能让网关尽快恢复注册。
注册状态验证用show sip-ua registrar status,输出里能看到已注册的账号、绑定地址和过期时间。如果看到Rejected,先检查运营商给的账号是否带区号或前缀,这个问题引起的问题我在第5章单独讲。
3.3 用debug命令验证呼叫到哪一步:看messages比猜配置快
配置完成后,不要急着拿电话狂拨,先用debug确认SIP信令走到哪一步。我最常用的两条命令是debug voip sip message和debug ccsip all。前者看SIP消息内容,后者看Cisco呼叫控制模块的处理过程。建议用debug voip sip message开始,输出更紧凑,不至于一秒钟刷上千行。
router# debug voip sip message SIP/2.0 100 Trying SIP/2.0 180 Ringing SIP/2.0 200 OK ... INVITE sip:01012345678@10.1.1.2:5060 SIP/2.0 From: "2001" <sip:2001@10.0.0.1> To: <sip:01012345678@10.1.1.2> Call-ID: C2A1B3D4-0002-4E5F-B8A9@10.0.0.1看到180 Ringing说明呼叫已经到被叫端并开始振铃,如果一直停在100 Trying说明对端没有继续处理或者路由没配对。Call-ID字段务必记下来,后续向运营商报障时,对方只要问Call-ID就能在IMS侧查到完整信令链路。我习惯在debug的同时开一个terminal monitor,这样SSH会话里也能实时看到输出。
debug输出刷屏时,用undebug all收掉。生产网关上debug不要开太久,尤其是debug ccsip all,日志量能把磁盘写满,建议只开debug voip sip message并配合访问控制。验证完注册和基本呼叫后立即关闭。
4. 对接运营商IMS或IP-PBX:SIP中继参数与show命令验证
4.1 把IMS接入做成一条SIP中继:session target与voice trunk两种做法
运营商IMS接入和传统PRI最大的区别,在于IMS不会给你一根物理线,而是给一个SIP服务器地址和一组账号。Cisco IOS上这个接入方式最常见的做法,是把它做成一条逻辑SIP中继。有人习惯沿用dial-peer,有人用新版voice trunk,两者都能实现,但应用场景略有不同。
用dial-peer做SIP中继,本质上就是定义一个固定的出向出口,session target写成IMS的IP或域名。这种方式灵活、命令最少,适合中小分支单中继场景。新版IOS还支持voice trunk对象,它把SIP中继当作一个独立的逻辑实体,可以在上面统一配置SIP profile、编解码、DTMF模式和媒体参数,然后再被dial-peer引用。区别在于,dial-peer方式每个拨号规则都要重复写一遍中继参数,voice trunk方式把中继参数收拢到一个对象里,多个dial-peer共用一套策略。
我用一个典型配置示例说明voice trunk的写法:
voice trunk IMS-TRUNK session protocol sipv2 session target ipv4:10.1.1.2:5060 voice-class codec 1 dtmf-relay rtp-nte no vad ! dial-peer voice 300 voip description Route calls via IMS trunk session trunk IMS-TRUNK destination-pattern 9T !这段配置的逻辑非常直白:先定义一条IMS-TRUNK中继,指定对端地址和媒体策略,然后在dial-peer里用session trunk IMS-TRUNK引用它。好处是如果换运营商或IMS地址变更,只需要改一处session target,不用翻遍所有dial-peer。no vad在这里的作用是关闭静音压缩,避免语音在静音时被切掉头尾,PSTN呼叫尤其建议关。
不管用哪种写法,对接IMS的核心还是那几条参数,session transport选UDP还是TCP要看运营商要求,绝大多数国内运营商默认用UDP 5060。如果运营商要求TLS,那就要额外配证书和sip profile,这里不展开。
4.2 对接IMS时必调的三个SIP参数:session timer、100rel/PRACK与re-INVITE
IMS对接之所以比传统IP-PBX麻烦,是因为IMS对SIP标准行为的遵循比较严格,参数不匹配直接导致呼叫失败或者通话被切断。我总结了三个必查参数,全部都在voice service voip的sip子模式和voice class sip里配置。
第一个是session timer。SIP会话定时器用来保活会话,默认值可能是1800秒,但有些IMS强制要求900秒。问题在于如果网关和对端对session timer的协商不一致,通话到定时器到期时会被强制断开,具体现象就是通话30分钟整被切断。我一般会在sip子模式下显式配置:
voice service voip sip session timer 900 session refresher uac midcall-signaling passthrusession refresher uac表示由网关作为刷新方发起re-INVITE,midcall-signaling passthru允许呼叫中间的SIP信令透传。第二个必调参数是100rel,也就是PRACK。有些IMS在收到INVITE后会先回100 Trying再回183 Session Progress并要求PRACK确认,如果不支持PRACK,呼叫会卡在早期媒体阶段。配置方式是voice-class sip里加rel1xx require或者rel1xx supported,具体看对端要求。
第三个是re-INVITE处理。通话建立后的呼叫保持、协商变更都会触发re-INVITE,如果网关在voice service voip里没有允许mid-call信令,对端发送的re-INVITE会被直接拒绝,表现为通话中按保持键后对方听不到声音。加上midcall-signaling passthru基本能规避大部分问题。
这三个参数没有统一模板,必须看对端SIP profile的要求。我的做法是接通后第一通电话就主动保持、再恢复,测的就是re-INVITE链路。
4.3 用show命令确认中继状态:sh sip calls、sh voice trunk与sh dial-peer summary
排障不能光靠猜,Cisco IOS给了一组查看命令,能快速定位问题在哪一层。我按使用频率排序,最常用的是show sip calls,它列出当前活动的SIP呼叫和每个呼叫的状态。输出里能看到每条呼叫的对端IP、状态、媒体地址和Call-ID,和debug抓到的信息能对应上。
router# show sip calls SIP Call Info: Call 1: Call-ID: C2A1B3D4-0002-4E5F-B8A9@10.0.0.1 State: Active From: <sip:2001@10.0.0.1> To: <sip:01012345678@10.1.1.2> Duration: 00:01:23看到State: Active说明呼叫已经建立。如果卡在Call Setup或者Incoming Call,基本可以判断是信令没走完。
show voice trunk用于查看voice trunk对象的状态,包括当前会话数和注册情况。show dial-peer voice summary则是看dial-peer的匹配统计,每一行会显示该dial-peer被匹配的次数,如果配置了出向dial-peer但匹配次数一直是0,说明拨号规则没套上。
我还有一个习惯:每次改完配置,用show running-config | section voice|dial-peer|sip-ua把三段配置一次性打出来,确认没有语法错误。配置丢失或重启后配置没保存,是网关类故障里最冤的一种。
5. 避坑与排查:Cisco IOS SIP网关最常见的五个翻车点
5.1 注册与呼叫建立阶段的三个坑:401循环、404拨号不匹配、只振铃不接续
先讲注册阶段的经典故障:REGISTER请求一直收到401,然后网关不再重发,注册状态变成Rejected。现象是sip-ua配置了账号密码,但show sip-ua registrar status一直看不到注册成功。原因通常是credentials和authentication里的用户名不一致,或者运营商IMS要求用户名带域后缀而网关只填了号码。解决方法是检查运营商给的SIP账号格式,有些IMS要求用户名写成8613912345678@domain,有些只需要纯号码,确认后把credentials和authentication两处改成完全一致。
第二个坑是外线拨入时网关回404。现象是从PSTN拨总机号码,听到的是一段空号音或运营商提示无法接通。原因往往是入向dial-peer的incoming called-number写的是E.164格式,但IMS送来的INVITE里的被叫号码不带国家码,或者带了+号。解决方法是先debug voip sip message看INVITE里的To字段到底携带什么号码格式,再调整incoming called-number或者加一条translation-profile把入向号码规整成统一格式。不要凭记忆猜号码格式,信令里写的才是真的。
第三个坑比较隐蔽:呼叫能建立、能振铃,但接听后没有声音。现象是分机拿起话筒后双方都听不到对方,但SIP信令显示呼叫已经变为Active。原因多半是媒体协商出了问题,网关发出的SDP里带的媒体地址不可达。最常见的场景是bind media source-interface绑定的接口和实际转发RTP的接口不一致,或者对端送来的RTP端口被防火墙拦了。解决方法是确认媒体地址,在网关上看show voice call status,看RTP流的实际收发地址是不是预期地址,然后检查会话所在接口的ACL有没有放行UDP 16384到32767这个RTP端口段。
5.2 通话保持与语音质量的两个坑:30秒挂断、单通与抖动
通话保持阶段的坑往往比呼叫建立更难查,因为它要等一段时间才出现。第一个典型现象是通话每隔30分钟整被挂断,两边都听到挂断音,时间点非常规律。原因就是第4章提到的session timer协商不一致。IMS要求900秒,网关还在用默认的1800秒,或者网关根本不发re-INVITE刷新会话,定时器到期后IMS主动拆线。解决方法是把session timer显式配成900,并用debug voip sip message确认INVITE消息里携带的Session-Expires头数值。
第二个是通话间歇性单通或者声音断断续续。现象是通话前几分钟正常,几分钟后对方听不清,或者干脆单通,但信令链路始终正常。原因有几个:一是RTP端口老化,防火墙里的UDP会话超时把媒体流切了;二是VAD静音压缩导致半双工错觉,三是编解码协商到了G.729但带宽不足。解决方法是先关VAD,这是成本最低的改动,在dial-peer下配no vad;然后查网络丢包和抖动,网关上的show voice call status能看到MOS评分和丢包率,我习惯把MOS低于3.5的呼叫直接抓包分析。
最后提一个注册层面的细节:有些运营商IMS会主动发送SIP OPTIONS探测网关存活状态,如果网关不响应,IMS会在几分钟内把注册状态标记为down。遇到这种情况,需要在voice service voip的sip子模式下配置options-keepalive相关参数,具体数值依据运营商要求。这类问题特点是注册状态在网关侧看着是正常的,但外线已经打不进来,非常容易误判。
6. 把Cisco IOS SIP网关交给使用方之前:一条命令加一个排障习惯
6.1 show voice call status:一张表看懂MOS、抖动和丢包
呼叫通不通只是第一步,语音质量才是用户真正感知到的东西。我每次在项目收尾时,都会拨一通测试电话,然后在通话保持状态下执行show voice call status。输出里有一组关键指标:MOS评分、抖动、丢包率和编解码类型。MOS低于4.0在PSTN场景下一般听感尚可,低于3.5就需要检查网络。抖动一般要求小于20毫秒,超过30毫秒就会有明显回声和断续感。丢包率在G.711下要求0,在G.729下允许小于1%,超过这个范围语音质量会断崖式下降。
这组数据不要只看一次,我习惯在通话的第1分钟、第10分钟各看一次,对比抖动和丢包是否随时间恶化。如果第一次正常第二次跳高,基本可以断定是网络拥塞或者中间设备缓存策略问题,和网关本身关系不大。
6.2 我的排障习惯:先分层、后抓包、带着Call-ID去问对端
最后分享一个我坚持了很多年的排障习惯。遇到SIP语音网关问题,我的第一反应不是开debug,而是先分清楚故障在哪一层:注册层、信令层、媒体层还是网络层。注册层看show sip-ua registrar status,信令层看debug voip sip message,媒体层看show voice call status和RTP抓包,网络层看ping和show interface统计。每层都有自己的验证命令,分层排查不会漏也不至于一头扎进抓包里出不来。
如果是和对端配合的问题,我会把抓包里的Call-ID、From头、To头、Session-Expires这几个字段整理好,连同时间点一起发给对端工程师。Call-ID是SIP世界里唯一定位一次呼叫的标识,有了它对方可以在IMS侧快速检索完整信令。这个过程比两边的工程师对着屏幕猜半天高效得多,也是我把一条翻车总结成工程经验的过程。希望帮到你。
本文还有配套的精品资源,点击获取