*本文已做过更改,如需参考,请转至《FS NAT穿越、单通及呼入30秒自动挂断解决》 *
*本文已做过更改,如需参考,请转至《FS NAT穿越、单通及呼入30秒自动挂断解决》 *
*本文已做过更改,如需参考,请转至《FS NAT穿越、单通及呼入30秒自动挂断解决》 *
重要的事情说三遍!!!
史上最完整的NAT穿越
开个玩笑了,可能是因为网上一大堆繁杂而又不太全面的文章太多了,也可能是自己的网络拓扑不太一样(最简单的一种),按网上的大堆文章来弄,期间各种调试FS各种internal,external参数,然而弄了两天并没有什么luan用!
网络拓扑
SIP客户端->外网->防火墙->FS
可以明显的看出,sip客户端是在一个网络环境,FS在另外一个网络环境,主要靠“外网”联系起来!
配置之路
var.xml
填上你的stun服务器,如:stun.ideasip.com、stun:stun.freeswitch.org,也可以设置成你的外网IP,具体操作你可以试试
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=stun:stun.ideasip.com"/>
<X-PRE-PROCESS cmd="set" data="external_sip_ip=stun:stun.ideasip.com""/>
具体可用的服务器可以参见(自己选):
stun:stun1.l.google.com:19302
stun:stun2.l.google.com:19302
stun:stun3.l.google.com:19302
stun:stun4.l.google.com:19302
stun:23.21.150.121
stun:stun01.sipphone.com
stun:stun.ekiga.net
stun:stun.fwdnet.net
stun:stun.ideasip.com
stun:stun.iptel.org
stun:stun.rixtelecom.se
stun:stun.schlund.de
stun:stunserver.org
stun:stun.softjoys.com
stun:stun.voiparound.com
stun:stun.voipbuster.com
stun:stun.voipstunt.com
stun:stun.voxgratia.org
stun:stun.xten.com
测试stun服务器是否可用(如测试 stun1.l.google.com:19302):
stun stun1.l.google.com:19302
如果返回你所在的服务网络外网IP地址加端口,证明stun服务器是可用的,类似如下:
222.85.X.X:53251
internal.xml
- 开启rport功能
<param name="NDLB-force-rport" value="true"/>
- 设置rtp自动调整功能,注意是false
<param name="disable-rtp-auto-adjust" value="false"/>
- 设置sip和rtp的外网地址(调用var.xml里面设置的stun或者你的外网IP参数)
<param name="ext-rtp-ip" value="$${external_rtp_ip}"/>
<param name="ext-sip-ip" value="$${external_sip_ip}"/>
- 设置acl参数,以此来判断内外网呼叫
<paramname="local-network-acl" value="lan"/>
external.xml
- 设置sip和rtp的外网地址(调用var.xml里面设置的stun或者你的外网IP参数)
<param name="ext-rtp-ip" value="$${external_rtp_ip}"/>
<param name="ext-sip-ip" value="$${external_sip_ip}"/>
acl.conf.xml
这里对应internal.xml里面的<paramname="local-network-acl" value="lan"/> ,设置ACL为(比如你的SIP所在的网络内网IP为192.168.10.5,则可以设置为192.168.10.0/24或者直接指定只允许192.168.10.5/32这个IP):
<list name="lan" default="deny">
<node type="allow" cidr="192.168.10.0/24"/>
</list>
这个ACL表示只允许内网网段为192.168.10.0/24的电脑连接,其它均拒绝
switch.conf.xml
设置RTP端口开放从10000到20000,你也可以使用默认(从16384到32768)的,但是有的防火墙最多只支持一次设置间隔200,多了要设置到你哭,比如华为的usg6550防火墙……这里我们设置10000个够了,如下:
<param name="rtp-start-port" value="10000"/>
<param name="rtp-end-port" value="20000"/>
brian.xml
为了兼容没有rport功能的终端,在brian.xml中加入
<variable name="sip-force-contact" value="NDLB-connectile-dysfunction"/>
在路由器(防火墙)上映射fs的sip端口和rtp端口
注意 * 端口号10000-20000对应的是switch.conf.xml预先修改的 rtp-start-port 和 rtp-end-port
| 端口号 | 协议 |
|---|---|
| 1719 | UDP |
| 1720 | TCP |
| 3478 | UDP |
| 3479 | UDP |
| 5002 | TCP |
| 5003 | UDP |
| 5060 | UDP&TCP |
| 5070 | UDP&TCP |
| 5080 | UDP&TCP |
| 8021 | TCP |
| 10000-20000 | UDP |
| 5066 | TCP |
| 7443 | TCP |
用以上方法,在云服务器上部署是可以听到声音,能正常运行,云服务器没有内网IP,查看网络连接直接显示的是外网IP
下面的填坑之路是在具有内网IP的服务器上做的NAT穿越解决方法:在SIP客户端添加stun就可以解决
填坑之路
听不到声音
这个时候拨打9664测试一下听不听得见音乐,或者直接拨打其它已经注册上去的一个分机,如果听不到声音,通过抓包分析,我这里的RTP走内网地址了,本来应该要走外网地址的才对。如下图(通过抓包解决问题):
客户端抓包呼叫流:

服务端抓包呼叫流:

从上两图可以清楚地看到服务端RTP流送到了SIP客户端的内网IP上,这显然是不行的,这也是听不到声音的最主要原因。
期间花了两天时间来测试调各种参数,包括换acl、把internal.xml中的local-network-acl填为domains、把internal.xml和external.xml中的ext-rtp-ip,ext-sip-ip都填为服务所在的外网IP,在IP前面加"auto-nat:"、直接更改为可用的stun服务器地址等都不行,要么是客户端送到服务器RTP的流是内网,要么服务器送到客户端的RTP是SIP的内网,要么两个都是内网IP,还是听不到声音。
更改客户端配置
由于本人使用的接入客户端是eyebeam,修改eyebeam的"SIP账号"->属性->网络拓扑->防火墙穿越->STUN服务器->使用指定服务器,填入你的STUN服务器,如我这里填的是“ stun.ideasip.com ”,其它客户端相信也有类似的配置。

测试拨打9664
拨打9664或者已经注册到服务上的另一客户端,听到了期盼已久的声音!至此,NAT穿越完美结束!
如果还是听不到声音,试着把5060、5080默认端口改一下,比如改成7890,7898这种没有占用的端口试试,有的运营商会和谐掉这两个端口,这样肯定就听不到声音了
后续
- 查看NATMAP 我机器上啥都没有……
命令 nat_map status
Nat Type: UNKNOWN, ExtIP:
NAT port mapping enabled.
0 total.
- 列出internal SIP Profile的状态
命令 sofia status profile internal
=================================================================================================
Name internal
Domain Name N/A
Auto-NAT false
DBName sofia_reg_internal
Pres Hosts 10.20.13.97,10.20.13.97
Dialplan XML
Context public
Challenge Realm auto_from
RTP-IP 10.20.13.97
Ext-RTP-IP stun:stun.ideasip.com
SIP-IP 10.20.13.97
Ext-SIP-IP 222.X.X.165
URL sip:mod_sofia@222.x.x.x:6729
BIND-URL sip:mod_sofia@222.x.x.x:6729;
maddr=10.20.13.97;transport=udp,tcp
HOLD-MUSIC local_stream://moh
OUTBOUND-PROXY N/A
CODECS IN OPUS,G722,PCMU,PCMA,GSM
CODECS OUT OPUS,G722,PCMU,PCMA,GSM
TEL-EVENT 101
DTMF-MODE rfc2833
CNG 13
SESSION-TO 0
MAX-DIALOG 0
NOMEDIA false
LATE-NEG true
PROXY-MEDIA false
ZRTP-PASSTHRU true
AGGRESSIVENAT true
CALLS-IN 2
FAILED-CALLS-IN 0
CALLS-OUT 0
FAILED-CALLS-OUT 0
REGISTRATIONS 2
嗯,正常情况下Ext-RTP-IP要么是STUN,要么是服务所在的外网IP, Ext-SIP-IP是你的服务所在的外网地址,如果不存在这两个参数,证明NAT没有成功。
如果还是不行,你需要一个SBC!
