SIP穿越NAT&FireWall解决方案
SIP
从私网到公网会遇到什么样的问题呢?
1.
包的地址转换。
2. SIP 消息里面的SIP 地址转换。
3. SIP 消息里面的SDP 中的RTP 地址转换。
网络现存结构复杂,SIP 服务提供商并不一定是NETWORK 提供商,很难要求客户只能使用某种方式的NAT&FireWall 。如何找出一种可以满足各种网络的SIP 应用解决方案呢?
NAT和Firewall 的基本原理
2. SIP 消息里面的SIP 地址转换。
3. SIP 消息里面的SDP 中的RTP 地址转换。
网络现存结构复杂,SIP 服务提供商并不一定是NETWORK 提供商,很难要求客户只能使用某种方式的NAT&FireWall 。如何找出一种可以满足各种网络的SIP 应用解决方案呢?
NAT和Firewall 的基本原理
首先,NAT
的几种方式:
Full Cone :当一台私网内的主机向公网发一个包,其本地地址和端口是{A:B} ,NAT 会将其私有地址{A:B} 转换成公网地址{X:Y} 并绑定。任何包都可以通过地址{X:Y} 送到该主机的{A:B} 地址上,NAT 会将任何发送到{X:Y} 的incoming 包的地址{X:Y} 转换成{A:B} 。
Partial/Restricted Cone :当一台私网内的主机向公网发一个包,其本地地址和断口是{A:B} ,NAT 会将其私有地址{A:B} 转换成公网地址{X:Y} 并绑定。任何包都可以通过地址{X:Y} 送到该主机的{A:B} 地址上,但是,NAT 只为第一个发往{X:Y} 的包绑定成{A:B}|{X:Y}<->{C:D}, 其中{C:D} 是那个包的源地址和端口。也就是说,只有来自{C:D} 的包才能于主机{A:B} 通信。
Partial 和Restricted Cone 的区别是Partial 只绑定incoming packet 的IP 地址,而Restricted Cone 会绑定incoming packet 的IP 地址和端口。也就是上面描述的那种情况。
Symmetric Cone :当一台私网内的主机向公网某台主机发送一个包,{A:B}à{C:D} 。NAT 会将其地址{A:B} 转换成{X:Y} ,并为其绑定成{A:B}|{X:Y}<->{C:D} 。NAT 只接受来自{C:D} 的incoming packet ,将它转给{A:B} 。也就是说,如果私网内的主机要向外面发送一个包,它必须要知道对方的公网IP 和端口。但如果对方也是处于一个私网内,它就很难获知对方的公网IP 和端口。
由此可见,Symmetric Cone 条件最严格,Partial/Restricted Cone 次之,Full Cone 条件最不严格。
下面再看看Firewall的基本策略:
Firewall 会判断所有的包是来自内部(Inside )还是外部(Outside) 。
Full Cone :当一台私网内的主机向公网发一个包,其本地地址和端口是{A:B} ,NAT 会将其私有地址{A:B} 转换成公网地址{X:Y} 并绑定。任何包都可以通过地址{X:Y} 送到该主机的{A:B} 地址上,NAT 会将任何发送到{X:Y} 的incoming 包的地址{X:Y} 转换成{A:B} 。
Partial/Restricted Cone :当一台私网内的主机向公网发一个包,其本地地址和断口是{A:B} ,NAT 会将其私有地址{A:B} 转换成公网地址{X:Y} 并绑定。任何包都可以通过地址{X:Y} 送到该主机的{A:B} 地址上,但是,NAT 只为第一个发往{X:Y} 的包绑定成{A:B}|{X:Y}<->{C:D}, 其中{C:D} 是那个包的源地址和端口。也就是说,只有来自{C:D} 的包才能于主机{A:B} 通信。
Partial 和Restricted Cone 的区别是Partial 只绑定incoming packet 的IP 地址,而Restricted Cone 会绑定incoming packet 的IP 地址和端口。也就是上面描述的那种情况。
Symmetric Cone :当一台私网内的主机向公网某台主机发送一个包,{A:B}à{C:D} 。NAT 会将其地址{A:B} 转换成{X:Y} ,并为其绑定成{A:B}|{X:Y}<->{C:D} 。NAT 只接受来自{C:D} 的incoming packet ,将它转给{A:B} 。也就是说,如果私网内的主机要向外面发送一个包,它必须要知道对方的公网IP 和端口。但如果对方也是处于一个私网内,它就很难获知对方的公网IP 和端口。
由此可见,Symmetric Cone 条件最严格,Partial/Restricted Cone 次之,Full Cone 条件最不严格。
下面再看看Firewall的基本策略:
Firewall 会判断所有的包是来自内部(Inside )还是外部(Outside) 。
一般,允许所有来自inside
的包发出去。
一般,允许来自Outside
的包发进来,但这个连接必须是由Inside
发起的。
一般,禁止所有连接由Outside
发起的包发进来。
一般,firewall
会允许几个信任的outside
主机,他们可以发起建立连接,并发包进来。
所有NAT 和Firewall 都是对于TCP/IP 层以下进行处理和过滤的,而SIP 应用的地址是在应用层。所以必须采用其他的途径来解决这一问题。
针对不同的NAT类型,可以有不同的解决方案。
1. UPnP
2. External Query
3. STUN
4. ALG
其中前3 种都是由SIP Client( 包括UA 和Proxy) 通过某种手段或协议在INVITE 之前获取自己的公网地址和端口。需要SIP Client 提供额外支持,并且也不适应所有的NAT 方式。
ALG(Application Layer Gateway) 适应所有NAT 方式,并不需要SIP Client 做任何额外的支持。它对Application 层的SIP 信令进行处理和修改,从而做到透明转换地址。
下面针对一个案例详细描述ALG 的解决方案。
SIP ALG 解决方案
ALG 修改SIP 消息里面的SIP 地址和端口和SDP 消息里面的RTP 地址和端口, 其中RTP 地址和端口要向RTP Proxy 请求获得,RTP Proxy 分配自己的一个空闲的地址和端口,并和这个Call 保持映射关系。并为分配给呼叫双方的地址和端口进行绑定,这样,呼叫双方的RTP 连接地址都是RTP Proxy, 由RTP Proxy 经过中转,发至真正的目的地。假设,有两个SIP Client 要进行通信,Ada 和Bob ,他们分别位于自己的Nat Server 后面:
其中两台NAT Server 都是Symmetric Cone 方式。
其信令流程如下:
1. Ada 发起信令,Invite Bob 。
IP Packet IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060 (SIP ALG)
SIP Msg IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060
SDP Body IP Address for RTP:
192.168.1.10:10024
2. 经过NAT Server ,NAT 将其私有地址转换成公网地址,并绑定,由于是采用Symmetric Cone 方式,所以还绑定目的的IP 地址。
{192.168.1.10:5060}|{128.96.41.1:5678}<->{128.97.41.56:5060}
IP Packet IP Address:
From: 128.96.41.1:5678
To: 128.97.41.56:5060 (SIP ALG)
SIP Msg IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060
SDP Body IP Address for RTP:
192.168.1.10:10024
3. SIP ALG 接受到该INVITE ,发现其包的IP 地址和SIP IP 地址不同,就判断其是经过NAT ,于是就将其相关的SIP IP 地址修改。
并检查它的Body 中是否是包含SDP 信息,如果是,且有RTP 地址,SIP ALG 就会去向RTP Proxy 请求一个公网RTP 地址来代替原有的RTP 地址。
IP Packet IP Address:
From: 128.97.41.56:5060
To: 128.96.63.25:5566
SIP Msg IP Address:
From: 128.96.41.1:5678
To: 128.96.63.25:5566 (下一跳的地址)
SDP Body IP Address for RTP:
128.97.44.5:3000
4. 因为Bob 不断的向SIP ALG 发送注册包,所以,它的NAT Server 始终为它保留着这么个绑定,{10.0.0.12:5060}|{128.96.63.25:5566}<->{128.97.41.56:5060} 。所以,由SIP ALG 发出的INVITE ,Bob 能收到。
Bob 返回200 OK ,包含SDP 信息。
IP Packet IP Address:
From: 10.0.0.12:5060
To: 128.97.41.56:5060
SIP Msg IP Address:
From: 10.0.0.12:5060
To: 128.97.41.56:5060 (下一跳的地址)
SDP Body IP Address for RTP:
10.0.0.12:10002
5. NAT Server 将其包的IP 地址修改。发往SIP ALG 。
6. SIP ALG 接受到该200 OK ,发现其包的IP 地址和SIP IP 地址不同,就判断其是经过NAT ,于是就将其相关的SIP IP 地址修改。
并检查它的Body 中是否是包含SDP 信息,如果是,且有RTP 地址,SIP ALG 就会去向RTP Proxy 请求一个公网RTP 地址来代替原有的RTP 地址。
IP Packet IP Address:
From: 128.96.63.25:5566
To: 128.96.41.1:5678
SIP Msg IP Address:
From: 128.96.63.25:5566
To: 128.96.41.1:5678 (下一跳的地址)
SDP Body IP Address for RTP:
128.97.44.5:3002
7. 此时,RTP Proxy 为这个Session 保持着这么个连接绑定
{128.97.44.5:3000|128.97.44.5:3002}
8. Ada 收到200 OK ,它认为对方的RTP 地址是128.97.44.5:3002 。将与其建立连接。
而Bob 认为对方的RTP 地址是128.97.44.5:3000 。将与其建立连接。
9. 当RTP Proxy 的3002 端口收到包,它可以从包地址获得Ada 的RTP 公网IP 。
当RTP Proxy 的3000 端口收到包,它可以从包地址获得Bob 的RTP 公网IP 。
从而,RTP Proxy 会将3002 端口收到的包转发到Bob 的RTP 公网IP 。
同样,RTP Proxy 会将3000 端口收到的包转发到Ada 的RTP 公网IP 。
这样,一个通话的连接就成功建立。
SIP ALG 的部署因为无论如何,都需要所有RTP 包经过RTP Proxy ,所以所有的MS 都要有修改SDP 的能力,而只有SIP ALG 需要有修改SIP 消息的能力。让用户配置自己的Proxy 是什么,避免公网的SIP Client 也经过SIP ALG ,造成没必要的消耗。
补充如果SIP ALG 发现INVITE 包的地址和SIP 地址是一致的话,它将不对这个包进行修改,它认为这个包是来自公网,或者SIP Client 具备了穿越NAT 的能力。但它会修改其SDP 的IP 地址。
ISSUE:
所有NAT 和Firewall 都是对于TCP/IP 层以下进行处理和过滤的,而SIP 应用的地址是在应用层。所以必须采用其他的途径来解决这一问题。
针对不同的NAT类型,可以有不同的解决方案。
1. UPnP
2. External Query
3. STUN
4. ALG
其中前3 种都是由SIP Client( 包括UA 和Proxy) 通过某种手段或协议在INVITE 之前获取自己的公网地址和端口。需要SIP Client 提供额外支持,并且也不适应所有的NAT 方式。
ALG(Application Layer Gateway) 适应所有NAT 方式,并不需要SIP Client 做任何额外的支持。它对Application 层的SIP 信令进行处理和修改,从而做到透明转换地址。
下面针对一个案例详细描述ALG 的解决方案。
SIP ALG 解决方案
ALG 修改SIP 消息里面的SIP 地址和端口和SDP 消息里面的RTP 地址和端口, 其中RTP 地址和端口要向RTP Proxy 请求获得,RTP Proxy 分配自己的一个空闲的地址和端口,并和这个Call 保持映射关系。并为分配给呼叫双方的地址和端口进行绑定,这样,呼叫双方的RTP 连接地址都是RTP Proxy, 由RTP Proxy 经过中转,发至真正的目的地。假设,有两个SIP Client 要进行通信,Ada 和Bob ,他们分别位于自己的Nat Server 后面:
其中两台NAT Server 都是Symmetric Cone 方式。
其信令流程如下:
1. Ada 发起信令,Invite Bob 。
IP Packet IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060 (SIP ALG)
SIP Msg IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060
SDP Body IP Address for RTP:
192.168.1.10:10024
2. 经过NAT Server ,NAT 将其私有地址转换成公网地址,并绑定,由于是采用Symmetric Cone 方式,所以还绑定目的的IP 地址。
{192.168.1.10:5060}|{128.96.41.1:5678}<->{128.97.41.56:5060}
IP Packet IP Address:
From: 128.96.41.1:5678
To: 128.97.41.56:5060 (SIP ALG)
SIP Msg IP Address:
From: 192.168.1.10:5060
To: 128.97.41.56:5060
SDP Body IP Address for RTP:
192.168.1.10:10024
3. SIP ALG 接受到该INVITE ,发现其包的IP 地址和SIP IP 地址不同,就判断其是经过NAT ,于是就将其相关的SIP IP 地址修改。
并检查它的Body 中是否是包含SDP 信息,如果是,且有RTP 地址,SIP ALG 就会去向RTP Proxy 请求一个公网RTP 地址来代替原有的RTP 地址。
IP Packet IP Address:
From: 128.97.41.56:5060
To: 128.96.63.25:5566
SIP Msg IP Address:
From: 128.96.41.1:5678
To: 128.96.63.25:5566 (下一跳的地址)
SDP Body IP Address for RTP:
128.97.44.5:3000
4. 因为Bob 不断的向SIP ALG 发送注册包,所以,它的NAT Server 始终为它保留着这么个绑定,{10.0.0.12:5060}|{128.96.63.25:5566}<->{128.97.41.56:5060} 。所以,由SIP ALG 发出的INVITE ,Bob 能收到。
Bob 返回200 OK ,包含SDP 信息。
IP Packet IP Address:
From: 10.0.0.12:5060
To: 128.97.41.56:5060
SIP Msg IP Address:
From: 10.0.0.12:5060
To: 128.97.41.56:5060 (下一跳的地址)
SDP Body IP Address for RTP:
10.0.0.12:10002
5. NAT Server 将其包的IP 地址修改。发往SIP ALG 。
6. SIP ALG 接受到该200 OK ,发现其包的IP 地址和SIP IP 地址不同,就判断其是经过NAT ,于是就将其相关的SIP IP 地址修改。
并检查它的Body 中是否是包含SDP 信息,如果是,且有RTP 地址,SIP ALG 就会去向RTP Proxy 请求一个公网RTP 地址来代替原有的RTP 地址。
IP Packet IP Address:
From: 128.96.63.25:5566
To: 128.96.41.1:5678
SIP Msg IP Address:
From: 128.96.63.25:5566
To: 128.96.41.1:5678 (下一跳的地址)
SDP Body IP Address for RTP:
128.97.44.5:3002
7. 此时,RTP Proxy 为这个Session 保持着这么个连接绑定
{128.97.44.5:3000|128.97.44.5:3002}
8. Ada 收到200 OK ,它认为对方的RTP 地址是128.97.44.5:3002 。将与其建立连接。
而Bob 认为对方的RTP 地址是128.97.44.5:3000 。将与其建立连接。
9. 当RTP Proxy 的3002 端口收到包,它可以从包地址获得Ada 的RTP 公网IP 。
当RTP Proxy 的3000 端口收到包,它可以从包地址获得Bob 的RTP 公网IP 。
从而,RTP Proxy 会将3002 端口收到的包转发到Bob 的RTP 公网IP 。
同样,RTP Proxy 会将3000 端口收到的包转发到Ada 的RTP 公网IP 。
这样,一个通话的连接就成功建立。
SIP ALG 的部署因为无论如何,都需要所有RTP 包经过RTP Proxy ,所以所有的MS 都要有修改SDP 的能力,而只有SIP ALG 需要有修改SIP 消息的能力。让用户配置自己的Proxy 是什么,避免公网的SIP Client 也经过SIP ALG ,造成没必要的消耗。
补充如果SIP ALG 发现INVITE 包的地址和SIP 地址是一致的话,它将不对这个包进行修改,它认为这个包是来自公网,或者SIP Client 具备了穿越NAT 的能力。但它会修改其SDP 的IP 地址。
ISSUE:
1.
如果SDP
描述的是单工工作的话,RTP
连接无法建立,因为RTP proxy
始终无法知道沉默方的RTP
公网IP
。
2. 每次建立RTP 连接,某一方的RTP 包可能会丢掉若干个,直到RTP proxy 获知另一方的RTP 公网IP 。
3. 是否应该强制任何RTP 包都要经过RTP Proxy ,无论它们都是来自公网,可以直接连接。我想是的,因为主叫方是不知道被叫方的网络环境的。
4. 如果多个RTP Proxy 进行均衡,如何保证为主叫方分配IP 的Proxy 和为被叫方分配IP 的Proxy 是一致的呢?(它们必须是同一台Proxy )
可以增加一个header ,比如RTP proxy ,这个header 只有SIP ALG 认识。
5. 如果SIP 消息加密,就无法修改其SIP 的IP 地址。
2. 每次建立RTP 连接,某一方的RTP 包可能会丢掉若干个,直到RTP proxy 获知另一方的RTP 公网IP 。
3. 是否应该强制任何RTP 包都要经过RTP Proxy ,无论它们都是来自公网,可以直接连接。我想是的,因为主叫方是不知道被叫方的网络环境的。
4. 如果多个RTP Proxy 进行均衡,如何保证为主叫方分配IP 的Proxy 和为被叫方分配IP 的Proxy 是一致的呢?(它们必须是同一台Proxy )
可以增加一个header ,比如RTP proxy ,这个header 只有SIP ALG 认识。
5. 如果SIP 消息加密,就无法修改其SIP 的IP 地址。