stun检查nat类型


nat(Session Traversal Utilities for NAT)会话穿越应用程序,可以让位于nat后的客户端找出自己的公网地址以及对应的Internet端口,最重要的是可以判断自己处于哪种nat类型之后,它是通过udp进行通信的。

下面重点讲怎么判断nat的类型。

一般将nat类型可以分为四种:全锥形,受限锥形,端口受限锥形,对称形。之所以是叫锥,可以想象一下圆锥,一个圆集中映射到一个点,也就是本地ip端口映射到nat服务器上面的公网ip和端口,其他任何远端ip和端口的网络都可以连接进来,这种就是全锥形,如果只有接收过连接的远端ip才能反向连接到本地ip,那这种就是受限形,其实就是ip受限形,如果再进行限制,只有接受过连接的远端ip和端口才能反连到本地ip,那这种就叫端口受限形。一般来说,本地服务器发起一个连接到任何远端ip,它对应的nat的端口都是不变的,如果发到不同的远端ip,它对应的nat的端口也不一样(公网ip也就是出口ip肯定是不变的),那这种就是对称形了,不同的远端ip对应不同的nat端口,形成一个对应关系,这种nat类型是不太好进行穿透的。

知道了上面的原理,检测nat的类型也就变得方便了。

首先本地程序发起一个udp连接到stun服务器,这个服务器你自己开发一个就行,stun接受的udp请求后,可以根据from记录下该请求的ip和端口,这个就是nat服务器是的出口ip了,然后根据这个ip和端口回复一条信息,把获取到的ip和端口作为信息回复回去,如果本地能接收到,说明网络是没有问题的,如果接收不了,说明block了。
这里获取到了出口ip后,可以和本地ip做对比,如果一样,那说明压根就没有nat了,可以直接bind一下,能绑定成功就说明没有nat。

本地重新发起一个请求到另外的stun服务器,通过同样的方法获取到出口ip和端口,将该端口和第一次的出口端口对比,如果变了,说明是对称形。

本地程序再发起一个请求给stun, stun服务器接收到该请求后,换一个出口ip给回复回去(重新发起一次请求),如果本地能收到回复,说明是全锥形的,换了一个ip也能接收到请求。如果接收不到请求了,对于非nat模式,那说明本地可能存在防火墙,nat下那还得继续探测。

本地发起一个请求到stun服务器,让stun换一个端口进行回复,如果本地能接收到,那说明是ip受限形,否则就是端口受限形。

至此,nat类型检测完成,这是udp通信下测试的结果,对于全锥形,需要使用tcp进行反连接探测,如果连接不上,可能服务器对tcp做了限制。如果能连接上,说明可以正常穿透使用,可以将nat改为0,注意,本地要有保活的措施,定期对外发起tcp连接,以获取公网ip和端口,反连就是对公网ip和端口重新发起连接的。

本文作者: nephen
本文链接: https://www.nephen.cn/posts/12334267/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!