webrtc stun协议

STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators),即简单的用UDP穿透NAT,是个轻量级的协议,是基于UDP的完整的穿透NAT的解决方案。它允许应用程序发现它们与公共互联网之间存在的NAT和防火墙及其他类型。它也可以让应用程序确定NAT分配给它们的公网IP地址和端口号。STUN是一种Client/Server的协议,也是一种Request/Response的协议,默认端口号是3478。

了解STUN之前,我们需要了解NAT的种类。

NAT对待UDP的实现方式有4种,分别如下:

1.    Full Cone NAT

完全锥形NAT,所有从同一个内网IP和端口号发送过来的请求都会被映射成同一个外网IP和端口号,并且任何一个外网主机都可以通过这个映射的外网IP和端口号向这台内网主机发送包。

2.    Restricted Cone NAT

限制锥形NAT,它也是所有从同一个内网IP和端口号发送过来的请求都会被映射成同一个外网IP和端口号。与完全锥形不同的是,外网主机只能够向先前已经向它发送过数据包的内网主机发送包。

3.    Port Restricted Cone NAT

端口限制锥形NAT,与限制锥形NAT很相似,只不过它包括端口号。也就是说,一台IP地址X和端口P的外网主机想给内网主机发送包,必须是这台内网主机先前已经给这个IP地址X和端口P发送过数据包。

4.    Symmetric NAT

对称NAT,所有从同一个内网IP和端口号发送到一个特定的目的IP和端口号的请求,都会被映射到同一个IP和端口号。如果同一台主机使用相同的源地址和端口号发送包,但是发往不同的目的地,NAT将会使用不同的映射。此外,只有收到数据的外网主机才可以反过来向内网主机发送包。

所有的STUN消息都包含20个字节的消息头,包括16位的消息类型,16位的消息长度和128位的事务ID。

 上图一共20字节

消息类型许可的值如下:

0x0001:捆绑请求

0x0101:捆绑响应

0x0111:捆绑错误响应

0x0002:共享私密请求

0x0102:共享私密响应

0x0112:共享私密错误响应

消息长度,是消息大小的字节数,但不包括20字节的头部。

事务ID,128位的标识符,用于随机请求和响应,请求与其相应的所有响应具有相同的标识符。16个字节。

消息头之后是0或多个属性,每个属性进行TLV编码,包括16位的属性类型、16位的属性长度和变长属性值。

属性类型定义如下:

MAPPED-ADDRESS

MAPPED-ADDRESS属性表示映射过的IP地址和端口。它包括8位的地址族,16位的端口号及长度固定的IP地址。

RESPONSE-ADDRESS

RESPONSE-ADDRESS属性表示响应的目的地址

CHASNGE-REQUEST

客户使用32位的CHANGE-REQUEST属性来请求服务器使用不同的地址或端口号来发送响应。

SOURCE-ADDRESS

SOURCE-ADDRESS属性出现在捆绑响应中,它表示服务器发送响应的源IP地址和端口。

CHANGED-ADDRESS

如果捆绑请求的CHANGE-REQUEST属性中的“改变IP”和“改变端口”标志设置了,则CHANGED-ADDRESS属性表示响应发出的IP地址和端口号。

USERNAME

USERNAME属性用于消息的完整性检查,用于消息完整性检查中标识共享私密。USERNAME通常出现在共享私密响应中,与PASSWORD一起。当使用消息完整性检查时,可有选择地出现在捆绑请求中。

PASSWORD

PASSWORD属性用在共享私密响应中,与USERNAME一起。PASSWORD的值是变长的,用作共享私密,它的长度必须是4字节的倍数,以保证属性与边界对齐。

MESSAGE-INTEGRITY

MESSAGE-INTEGRITY属性包含STUN消息的HMAC-SHA1,它可以出现在捆绑请求或捆绑响应中;MESSAGE-INTEGRITY属性必须是任何STUN消息的最后一个属性。它的内容决定了HMAC输入的Key值。

ERROR-CODE

ERROR-CODE属性出现在捆绑错误响应或共享私密错误响应中。它的响应号数值范围从100到699。

下面的响应号,与它们缺省的原因语句一起,目前定义如下:

400(错误请求):请求变形了。客户在修改先前的尝试前不应该重试该请求。

401(未授权):捆绑请求没有包含MESSAGE-INTERITY属性。

420(未知属性):服务器不认识请求中的强制属性。

430(过期资格):捆绑请求没有包含MESSAGE-INTEGRITY属性,但它使用过期

的共享私密。客户应该获得新的共享私密并再次重试。

431(完整性检查失败):捆绑请求包含MESSAGE-INTEGRITY属性,但HMAC验

证失败。这可能是潜在攻击的表现,或者客户端实现错误

432(丢失用户名):捆绑请求包含MESSAGE-INTEGRITY属性,但没有

USERNAME属性。完整性检查中两项都必须存在。

433(使用TLS):共享私密请求已经通过TLS(Transport Layer Security,即安全

传输层协议)发送,但没有在TLS上收到。

500(服务器错误):服务器遇到临时错误,客户应该再次尝试。

600(全局失败):服务器拒绝完成请求,客户不应该重试。

UNKNOWN-ATTRIBUTES

UNKNOWN-ATTRIBUTES属性只存在于其ERROR-CODE属性中的响应号为420的捆绑错误响应或共享私密错误响应中。

REFLECTED-FROM

REFLECTED-FROM属性只存在于其对应的捆绑请求包含RESPONSE-ADDRESS属性的捆绑响应中。属性包含请求发出的源IP地址,它的目的是提供跟踪能力,这样STUN就不能被用作DOS攻击的反射器。

属性空间分为可选部分与强制部分,值超过0x7fff的属性是可选的,即客户或服务器即使不认识该属性也能够处理该消息;值小于或等于0x7fff的属性是强制理解的,即除非理解该属性,否则客户或服务器就不能处理该消息。

过程:

客户端位于NAT后面, STUN Server位于公网中。 具体的IP和端口如下:

Client的IP地址和端口号为:     IP_C 和 Port_C

NAT的映射后的IP和端口号为:IP_N 和 Port_N

STUN的IP地址和端口为:        IP_S1  IP_S2 和 Port_S1 Port_S2

STEP1:验证客户端是否在NAT后面

从客户端发送一个UDP包到 IP_S1 + Port_S1, STUN收到后会把 IP_N+Port_N 保存到UDP包中作为对客户端请求的响应。然后把这个响应发送到 IP_N+Port_N。

无论客户端前面的NAT是什么类型,客户端都应该能够收到这个响应。 如果没有收到,要么是STUN Server不存在(或者你写错了地址或端口), 要么是你的NAT拒绝一切UDP包从外部进入。

当客户端收到响应数据时,我们就能从中得到 IP_N+Port_N, 也就是说我们从这一步能够得到NAT的外网地址和端口号。

拿到NAT的外网地址和端口号后,用其IP和client自身的IP地址进行比较:

如果相同,说明client具有公网地址,它没有在NAT后面。

如果不同,说明client在NAT后面,我们还要进行更多验证。

STEP2:验证我们的NAT是不是 Full Cone NAT

从客户端发送一个UDP包到 IP_S1 + Port_S1,请求Stun Server使用  IP_S2 + Port_S2 对我们的请求进行响应。

如果能收到响应数据: 说明NAT是 Full Cone NAT, 因为NAT来者不拒,不对数据进行任何过滤。

如果未收到响应数据:  我还需要进一步验证NAT的类型

STEP3:验证我们的NAT是对称NAT还是Cone NAT

从客户端发送一个UDP包到 IP_S2 + Port_S2, STUN收到后会把 IP_N+Port_N 保存到UDP包中作为对客户端请求的响应。然后把这个响应发送到 IP_N+Port_N。

这个测试中,我们关心的是UPD包中的数据, 如果包中的 Port_N 与 STEP1中的 Port_N是相同的,那么我们就可以肯定,这是个一个Cone NAT,如果不同那么就说明是个对称NAT。

STEP4:区分 Restict Cone NAT 和 Port Restrict Cone NAT

从客户端发送一个UDP包到 IP_S1 + Port_S1, 要求 Stun Server 用 IP_S1 + Port_S2 返回响应给client。

如果client能收到:说明是 Restrict Cone NAT

如果收不到: 说明时 Port Restrict Cone NAT

整个过程就结束了,除了对称NAT外,我们都能得到NAT的外网IP和端口,以及NAT的类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值