![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111432873.jpg)
图片来自于互联网
我们一说到NAT问题,读者马上就会联想到路由器配置或者路由器的地址转换方面的内容。今天,我们针对应用层的NAT-ALG进行一个比较完整的详解介绍,帮助读者进一步加深对SIP中的ALG配置,和其带来的影响。
1、ALG背景介绍
大部分的读者可能已经了解了网络OSI的架构,这里不再做过多介绍。ALG全称是Application-level gateway。其应用包括很多。我们使用的SIP是其中一种。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111419404.jpg)
图片来自于互联网
ALG支持4种功能,其中一个比较重要的功能就是“防火墙”功能。注意,这里的防火墙是加了引号的,因为在当前针对SIP的部署环境中,SBC承担了SIP防火墙的功能。关于SBC的完整的介绍,读者可以查阅笔者的历史文档,笔者对SBC部署发布了大量的技术资料,因此,这里不再重复。
如何搭建一个完整免费的边界会话控制器(SBC)测试场景
ALG可以把网络层的地址公网地址和内网地址进行NAT处理转换,实现内外网进行互联互通。在具体的实际应用中,ALG会重写一些SIP修改的消息内容来保证SIP服务器端和SIP终端之间地址的统一,保证其连接正常。这里,读者一定要注意几个需要注意到提示:
- ALG仅对应用层(SIP/SDP)的消息进行重写
- ALG仅针对NAT规则进行处理,如果没有NAT问题,无需ALG
- 在NAT后面的SIP设备不会感觉ALG的存在
因为大部分的SIP网络应用基本上都涉及了外网用户注册的问题,设备在NAT后,或者SIP服务器是公网部署。所以部署方案会带来很多潜在的问题。很多时候,在一些中小型企业通信的部署环境中,通过修改路由器的ALG配置可以解决一定的问题。但是,随着部署环境越来越复杂,客户对网络使用的灵活性要求越来越高,因此VOIP解决方案部署和NAT问题一直处于一种并存状态,这种状态给客户带来很多呼叫问题,包括单通,呼叫掉线,呼叫后无语音等问题。通过ALG开启或者关闭的设置,一些简单的问题都可以被轻松处理。接下来,我们具体介绍一下ALG针对SIP和SDP到底做了哪些处理。
2、ALG到底做了哪些处理
首先说明,ALG可以做NAT转换同样的工作,但是,ALG仅在第七层中进行处理。因为ALG是路由器的内置功能,因此,ALG主要做以下几个方面的工作:
- ALG是在消息离开路由器之前修改SIP/SDP应用的必要的消息
- ALG替换使用公网地址和端口替换SIP设备的内网地址和端口
简单示例说明,如果一个在内网的SIP终端需要和公网的SIP服务器连接,它首先需要通过路由器出局,并且告诉公网SIP服务器其SIP终端的公网地址。否则,SIP公网服务器不能和一个私人网IP的终端进行通信。那怎么办呢?只能通过路由器的ALG转换一个公网地址,然后和SIP服务器连接互通,返回时,路由器再通过这个绑定消息返回到内网SIP终端。这就是ALG简单的工作原理。在ALG处理中,SIP和SDP都需要进行修改处理:
- IP地址和端口修改
- 超时设置,媒体转发设置
- ALG修改SIP头中的Via和Contact,有的路由器也可能修改Route和Record- Route头。
- ALG修改SDP消息体中的m=,c=和o=,有时也修改a=。这些参数的具体内容,参考RFC4566-5章节
注意,在七层协议中,ALG和proxy服务器的地址转换有所不同。ALG设置无需SIP用户端进行配置,而proxy则需要用户端或者SIP服务器进行适当配置。以下示例就是一个典型的在路由器上开启ALG功能设置以后,SIP内网终端连接外网SIP服务器时的一个呼叫请求,在这个呼叫请求,SIP终端的Via,Contact发生转换的流程,ALG把Via和Contact通过公网地址进行了修改,替换为路由器公网地址,然后发送到SIP服务器。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111422491.jpg)
图片来自于互联网
我们讨论了关于ALG处理的一些参数。为了解决NAT问题,其实很多终端或者服务器端已经增加了针对NAT的功能支持,可以非常友好地解决NAT问题。但是,还有一部分产品没有支持NAT检测功能。因此,有时需要ALG开启,有时又需要ALG关闭。接下来,我们将讨论开启或者关闭ALG的必要性。
3、开启ALG功能设置
现在NAT问题非常普遍,很多SIP终端设备已经具备了NAT检测功能。但是市场上一些SIP终端(可能思科话机和比较老的品牌的话机有一部分不支持NAT检测)仍然没有支持NAT检测。不支持NAT检测功能的SIP终端对七层应用中消息写入一个私网IP地址。远端SIP服务器就会根据这个私网地址返回SIP响应。因为这个SIP终端是在NAT背后的私网地址,所以,SIP服务器端返回的消息永远不会抵达SIP终端。这样的话,类似这样的SIP终端就需要路由器开启ALG支持,通过ALG来修正到正确的IP地址上。如果SIP终端是在NAT背后的话,并且此SIP终端没有支持NAT检测,那么,这些设备就需要开启路由器的ALG功能设置。过路由器以后,没有开启ALG功能。路由器出局的IP地址仍然是一个私网地址。如下示例:
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111424255.jpg)
开启路由器的ALG功能以后,SIP服务器/IPPBX收到的SIP和SDP地址则修改为其公网地址,包括SIP header和SDP消息体内容。在下面的示例中,我们在路由器开启了ALG设置,SIP服务器可以收到其带公网地址的SIP/SDP消息。这样的话,不支持NAT检测的SIP终端如果路由器开启了ALG设置的话,则可以成功修改相关IP地址,可以保证和外网SIP服务器进行正常互通。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111427342.jpg)
因此,如果是不带NAT检测功能的终端,如果在NAT环境下,大部分情况下需要开启ALG功能。
4、关闭ALG的设置
前面我们讨论了在一些必要的SIP终端缺乏支持NAT检测功能的时候,需要开启ALG功能来解决公网IP地址的问题。但是,在很多场景中,SIP呼叫业务又不需要开启ALG功能。很多时候,我们经常听到技术人员说“检测路由器,关闭ALG设置”。确实,关闭ALG设置可以解决很多问题。但是,我们在什么时候需要关闭ALG呢?通常情况下,有几种情况需要读者考虑关闭ALG功能:
- SIP设备支持NAT检测功能
- SIP服务器是在NAT背后的网络环境中, SIP终端通过外网呼叫内网SIP服务器
- SIP服务器部署在公网环境,SIP终端在带NAT的环境中
在当前的部署环境中,我们看到的环境大部分是SIP服务器端支持NAT检测,SIP终端很少需要NAT检测的设置。所以,很多厂家,包括一些开源的SIP软交换或媒体服务器都能够支持NAT检测设置。如果是一个能够检测NAT的SIP服务器,它可以检测到自己的公网IP地址,并且发送SIP消息之前,会把自己的公网地址写入到SIP和SDP消息中。NAT检测可以绑定某些外网的分机,通过修改地址的方式发送到NAT环境以外的SIP终端。现在,我们讨论两个基本点使用场景。一种是SIP服务器或者IPPBX在NAT背后场景。如果此SIP服务器在NAT背后的话是这样处理的,ALG关闭以后,在内网的SIP服务器或者IPPBX会自动检测NAT设置,在发送SIP消息前修改SIP/SDP中的内网地址为公网地址,然后发送到外网的SIP终端,SIP终端就会收到一个带公网地址的SIP服务器的SIP/SDP消息,这样就会保证其互通成功。如果这种环境下开启ALG设置的话,可能会干扰SIP/SDP地址的发送。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111429960.jpg)
另外一种情况是SIP服务器或者IPPBX部署在公网环境或者云平台,SIP分机在带NAT的内网环境中。通常的处理方式可以是这样的:在SIP 服务器创建分机时,其分机属性设置支持NAT=yes以后,内网的SIP终端对SIP服务器端发送消息,路由器的ALG是关闭状态,SIP服务器收到SIP终端的消息后,包括其SIP终端的内网地址和SDP消息,看到分机设置为NAT=yes的设置,SIP服务器就会意识到有一个来自带NAT处理请求的SIP终端,这个终端要求修改SIP/SDP的内网地址为发送消息的公网地址。外网的SIP 服务器或者IPPBX就会替换掉Via中的SIP内网地址为一个Receivedd IP地址。SIP服务器通过这个Via 中的IP地址返回到公网地址和SIP终端。以下是一个FreePBX中关于NAT=yes的设置策略,这个参数设置比较智能地解决了NAT问题,同时也不需要开启路由器的ALG设置。
这里,路由器的ALG是关闭状态,因此SIP终端的内网IP地址就会发送到SIP服务器端,根据NAT=yes的设置选项,SIP服务器端修改了Via此SIP的公网地址,然后返回到此公网。这样的设置可以解决大部分的NAT问题。注意,有一些路由器也会干扰消息的处理,如果关闭ALG不能工作的话,技术人员需要开启ALG设置做进一步的测试。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105112512489.jpg)
因此,如果SIP服务器/IPPBX那个智能支持一个NAT=yes的选项,SIP服务器端自己首先进行NAT处理,无需开启路由器的ALG,可以帮助用户能够快速智能地解决大部分的问题。
提醒读者,开源Asterisk或者FreeSWITCH都能非常智能地支持类似的功能,具体的设置语法包括:
FreeSWITCH拨号规则中使用 <condition field="${sip_nat_detected}" expression="true">
Asterisk中的PJSIP配置文件中的local_net 和external_media_address等参数
如果通过FreePBX界面配置的话,参考www.freepbx.org.cn 的技术资料
5、ALG超时设置和媒体转发讨论
除了我们刚才讨论的是否开启ALG NAT功能以外,关于ALG设置还有两个比较重要的功能,它们分别是ALG超时设置和ALG媒体转发功能(sip-direct-media)。相对ALG地址的转换以外,这两个功能使用的场景可能相对比较少,但是它们有时仍然可能对呼叫产生一定的影响。在SIP会话处理过程中,一个呼叫可能涉及了多个定时器,包括最底层的路由器的UDP超时设置和SIP服务器/IPPBX端的SIP终端的会话的超时设置。但是,这些超时设置取值的大小会引起相互之间的冲突。例如,如果路由器的UDP超时设置是60秒的话,SIP服务器的SIP终端超时设置为120秒,那么,路由器中ALG的这个UDP超时会首先启动,超时后,UDP端口可能就会关闭,SIP服务器仍然多关闭的端口发送SIP呼叫的话,最终呼叫就会失败。因此,路由器的ALG超时设置一定要高于SIP服务器的各种会话超时设置-keepalive(注册超时,option超时,呼叫超时设置)的最低值,这样可以保证SIP服务器端的SIP终端可能始终获得开放的UDP端口。
在一些特殊情况下或者SIP服务提供商为了节省带宽费用,SIP呼叫需要支持媒体转发功能,绕过了SIP服务器的媒体处理能力支持,直接转发到其他媒体服务器。通常情况下,如果需要支持类似的功能的话,技术人员需要在SIP服务器/IPPBX端进行设置,现在的PBX都有类似的功能支持。这样的可以降低直接对接的SIP媒体服务器的负载,降低了带宽资源的耗费,提高了点对点呼叫的效率提高,但是会导致SIP服务器录音丢失,CDR记录缺乏,缺乏呼叫控制等其他问题。路由器的ALG也可以支持类似的功能(sip-direct-media),如果用户在路由器端的ALG上设置了类似的功能,那么,呼叫的媒体转发就会直接在ALG上进行处理。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105111430530.jpg)
6、ALG相关工具
目前很多工具可以排查ALG的问题。Wireshark是首选的排查工具,用户可以通过对路由器抓包来观察进入路由器和离开路由器期间地址的变化。路由器开启ALG以后,抓包测试SIP服务器地址,或者终端地址的变化。有时,一些用户如果不能直接访问路由器的设置的话,也可以下载测试工具来检查自己的路由器是否开启或者关闭了ALG设置。如下示例,如果笔者的网络中支持了ALG开关,ALG检测工具可以检测到true或者false的设置。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105112426963.jpg)
测试结果可以参照此说明来对照检查:
- If the results = False then a SIP ALG was not detected by the client.
- If the results = True then a SIP ALG is active and must be turned off.
ruby sip-alg-detector-daemon.rb -i 99.88.77.66
具体使用方式参考:
sip-alg-detector
https://github.com/ibc/sip-alg-detector
7、路由器ALG功能的局限性
当前的SIP呼叫业务的要求越来越复杂,本身路由器针对ALG功能支持相对比较简单,它天生具有一定的局限性。所以,如果使用SIP呼叫时,很多用户一般都关闭了ALG功能,通过SBC来处理SIP呼叫业务。现在,我们讨论几个关于ALG功能局限性话题:
根据目前市场上,用户对ALG的反馈,一些路由器厂家针对ALG或者SIP设置功能的支持不友好,带来一些不稳定的因素,所以很多用户一般选择关闭ALG功能。
ALG在NAT处理过程中替换一些必要的地址,有可能会替换掉SIP消息中的Call-ID的IP地址参数。如果修改了call-id的话,就会导致整个SIP会话管理出现问题,同一呼叫中系统出现了不同的会话消息,呼叫就会失败。
一些兼容性不好的路由器针对ALG的语法构建支持不好,很多时候在重写SIP消息时,可能会出现一些非法的字符,ALG处理以后的SIP内容格式破坏了SIP语法格式,SIP服务器端解析消息出现问题。
ALG仅支持了SDP的Payload,缺少针对SIP的其他支持,例如加密的SDP,TLS,FQDN解析处理,SIP认证处理机制,IPv6环境中对SIP的支持比较弱等问题。
针对SIP终端支持的BLF功能,其ALG兼容性相对比较弱(ALG仅支持3000-byte SIP 消息数据)。因为BLF需要产生大量的Notify消息,这些消息数据会超过ALG所限定的数据量。大家可以想象一下,如果几百台SIP话机都开启了BLF功能的话,都需要经过ALG处理的话,它们之间相互交互交互就会导致路由器负载很高。如果因为大量数据交换引起系统的稳定性问题,也可能最终导致其他的消息格式错误。因为UDP数据损坏导致的问题已经是SIP呼叫的一个大的问题。UDP Fragmentation Breaks SIP in Today's IP-PBXs
http://blog.tmcnet.com/third-screen/2009/03/udp_fragmentation_breaks_sip_in_todays_ip-pbxs.html
ALG缺少针对SIP methods和安全,其他SIP拓展的支持。市场上,大部分的路由器缺少专门针对SIP应用等功能比较完善的支持,一些厂家也针对ALG增加了一些针对SIP协议场景的拓展功能,因此,ALG功能得到了一定的提升。但是,其功能仍然很难完全满足运营级SIP呼叫的业务需求。毕竟,路由器的产品定位和会话边界控制器(SBC)的定位是不一样的。因此,如果需要非常专业的专门针对SIP和媒体处理的业务需求,强烈建议用户使用SBC来管理SIP呼叫和其他相关的业务功能。
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105112316420.jpg)
通过SBC实现SIP分机的外网注册功能
8、总结
路由器的ALG配置一直是用户非常关心的话题。笔者认为,通过本文章完整的介绍,读者可以基本上了解了关于ALG的功能,启用/关闭ALG的条件场景,以及ALG目前的局限性。
首先,笔者介绍了ALG的使用背景和技术特点,然后笔者针对具体的场景分别做了不同的说明。用户需要在什么时候开启ALG功能,什么时候关闭ALG功能。通过非常细节的拓扑图示例说明了工作的流程。然后,笔者介绍了几款关于ALG检测的实用工具,用户可以直接通过本地根据来检查路由器开启状态。最后,笔者讨论了ALG的一些局限性,帮助读者能够对ALG有一个完整专业的认识,也帮助用户能够了解针对SIP的部署的解决方案-SBC。通过SBC部署满足越来越复杂的SIP相关技术需求。
最后,笔者这里再次说明,本人没有可能耗费太多精力去测试多台路由器的ALG功能,因此不会针对每一款产品做出非常准确的评价,因此,在文章编写过程中可能出现一些错误的表述,望读者谅解。因为路由器厂家对ALG功能支持的力度有所不同,可能导致不同的设置结果。因此,强烈建议读者自己亲自在自己的环境中,通过不同配置,然后使用排查工具来进行实验验证。
参考资料:
https://tools.ietf.org/html/rfc2663
https://github.com/ibc/sip-alg-detector
https://tools.ietf.org/html/rfc4566#section-5
https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipaddr_nat/configuration/xe-3s/nat-xe-3s-book/iadnat-fw-sip-alg-hardng.html
https://wiki.asterisk.org/wiki/display/AST/Configuring+res_pjsip+to+work+through+NAT
https://www.researchgate.net/publication/291299719_Firewall-friendly_VoIP_secure_gateway_and_VoIP_security_issues/link/56c54e3a08ae736e704719a1/download
https://support.ringlogix.com/index.php?/Knowledgebase/Article/View/167/38/sip-alg-detector
https://fortinetweb.s3.amazonaws.com/docs.fortinet.com/v2/attachments/01b12c6d-1a17-11e9-9685-f8bc1258b856/fortigate-sip-60.pdf
https://www.juniper.net/documentation/en_US/junos/topics/topic-map/security-sip-alg.html
https://www.ecg.co/blog/125-sip-and-fragments-together-forever
![](http://www.ctiforum.com/uploadfile/2019/1105/20191105112218972.jpg)
![](http://www.ctiforum.com/uploadfile/2019/1028/20191028102113762.jpg)
关注微信公众号:asterisk-cn,获得有价值的Asterisk/SIP技术和行业分享
权威Asterisk freepbx FreeSBC技术文档: www.freepbx.org.cn
完整企业融合通信商业解决方案:www.hiastar.com
如何使用FreeSBC+FreeSWITCH/Asterisk,qq技术分享群:334023047