环境说明
最近需要搭建一个内外网sip通信的环境,大概拓扑如下:
client1和SIP server都在内网,client2在外网,三者都经过防火墙做NAT,防火墙会开启ALG功能,内外网互相访问使用过NAT的公网IP,内网访问使用私网IP。
使用软件
- SIP server使用opensips
- client1 和client2使用eyeBeam和EasySip,对于不同sip客户端以后会具体说明
实现功能
- 内外网client之间能够正常打电话
- client1和client2之间的sip 通话控制连接由sever代理client1与client2实现,通话数据传输由client1和client2之间实现
- client1和client2之间的通话数据由RTP传输
环境配置
- 搭建opensips server + RTPproxy环境
opensips server搭建可以参考https://blog.csdn.net/smileyan9/article/details/86092036
rtpproxy 安装可以参考 https://blog.csdn.net/fg4215828/article/details/60869396
需要注意的是osipsconfig安装需要安装USE_NAT和ENABLE_TCP
安装过程有报错可以通过tail /var/log/messages查看
附使用的opensips.cfg的关键配置
alias=172.30.1.32
listen=udp:10.226.6.1:5060
listen=tcp:10.226.6.1:5060
#### NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:[email protected]")
modparam("nathelper", "received_avp", "$avp(i:42)")
loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:10.226.6.1:12221")
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
-
开启RTP
rtpproxy -A 172.30.1.32 -l 10.226.6.1 -s udp:localhost:12221 -F
rtpproxy -A 172.30.1.32 -l 10.226.6.1 -s udp:localhost:12222 -F -
opensips常用指令
opensipsctl start/stop/restart 开启/关闭/重启服务
opensipsctl ul show 查看online的用户
opensipsctl ul rm [] 删除用户
[root@localhost ~]# opensipsctl ul show
Domain:: location hash_size=512
AOR:: 8002
Contact:: sip:[email protected]:61733;transport=udp Q=
ContactID:: 417216284229585379
Expires:: 271548
Callid:: 83156025-0103-7252-b1df-bfb99aab6af8
Cseq:: 31118
User-agent:: JdMee/v1.0.58.550
State:: CS_SYNC
Flags:: 0
Cflags:: NAT
Socket:: udp:10.226.6.1:5060
Methods:: 7535
AOR:: 8001
Contact:: sip:[email protected]:57098;transport=udp Q=
ContactID:: 417427390462002824
Expires:: 259073
Callid:: 56e11dbe-af8e-2291-add8-ffccdede2435
Cseq:: 2509
User-agent:: JdMee/v1.0.58.550
State:: CS_SYNC
Flags:: 0
Cflags:: NAT
Socket:: udp:10.226.6.1:5060
Methods:: 7535
- client 1和client2能够注册到sip server
需要使用拨号的号码和密码,外网client注册的server ip是过NAT的公网IP,内网client注册使用server ip的私网IP
8001 为client1
8002 为client2
使用EasySIP
使用eyeBeam
需要注意的是本地实验环境在虚拟PC上,没有声卡,有些sip客户端需要声卡才能使用,拨通后会显示正在连接却没有RTP数据。
本地测试,用EasySip拨打,eyeBeam接收会有RTP数据。
实验结果
内呼外,client1拨打client2
实现过程
client1与server控制连接协商
INVITE报文携带message body,携带了client1的私网IP,以及client1进行数据通信的端口13328
200 OK携带message body,connection information为client2过NAT后的公网IP,以及client2进行数据通信的端口52344
client2与server控制连接协商
client2端抓包
INVITE报文携带message body,connection information为client1过NAT后的公网IP,以及client1进行数据通信的端口13328
200 OK携带message body,connection information为client2私网IP,以及client2进行数据通信的端口52344
client1端数据抓包
client2端数据抓包
可以看到client1和client2的数据连接在过防火墙之前都是私网IP,过防火墙后转换为各自的公网IP。数据RTP访问的就是对应200OK和INVITE报文中携带的公网IP和端口。
外呼内,client2拨打client1
实现过程:
client2端控制连接抓包
INVITE报文携带message body,携带了client2的私网IP,以及client2进行数据通信的端口17210
200 OK携带message body,connection information为client1过NAT后的公网IP,以及client1进行数据通信的端口53246
client1端控制连接抓包
INVITE报文携带message body,携带了client2过NAT后的公网IP,以及client2进行数据通信的端口17210
200 OK携带message body,connection information为client1私网IP,以及client1进行数据通信的端口53246
client1端数据抓包
client2端数据抓包
可以看到client1和client2的数据连接在过防火墙之前都是私网IP,过防火墙后转换为各自的公网IP。数据RTP访问的就是对应200OK和INVITE报文中携带的公网IP和端口。
这种环境影响因素很多,比如:受客户端影响,受防火墙ALG功能影响。
不同客户端对过NAT处理会不相同,本地测试遇到过,由于是双网卡PC,使用Blink客户端软件,控制连接正常,但是message body中带的ip不是自己网卡控制连接的ip,变成PC管理网卡的IP,导致传输数据从另外一块网卡出去了-_-!!!
不同防火墙ALG对SIP的处理不同,这个就不具体说了。