在计算机网络中;网络地址转换(Network Address Translation;缩写为NAT);也叫做网络掩蔽或者IP掩蔽(IP masquerading);是一种在IP数据包通过路由器或防火墙时重写来源IP地址或目的IP地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有IP地址访问因特网的私有网络中。1990年代中期;NAT是作为一种解决IPv4地址短缺以避免保留IP地址困难的方案而流行起来的。
NAT虽然名为网络地址转换;但是常见的工作模式实际上是NAPT(网络地址端口转换)。这种方式支持端口的映射;并允许多台主机共享一个公网IP地址。 支持端口转换的NAT又可以分为两类;源地址转换和目的地址转换。前一种情形下发起连接的计算机的IP地址将会被重写;使得内网主机发出的数据包能够到达外网主机。后一种情况下被连接计算机的IP地址将被重写;使得外网主机发出的数据包能够到达内网主机。实际上;以上两种方式通常会一起被使用以支持双向通信。NAPT维护一个带有IP以及端口号的NAT表;结构如下;
| 内网IP&Port | 外网IP&Port | |-------------------|----------------------| | 192.168.1.55:5566 | 219.152.168.222:9200 | | 192.168.1.59:80 | 219.152.168.222:9201 | | 192.168.1.59:4465 | 219.152.168.222:9202 |
Full cone NAT(即一对一NAT): 一旦一个内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort);所有发自(iAddr:iPort)的包都经由(eAddr:ePort)向外发送。任意外部主机都能通过给(eAddr:ePort)发包到达(iAddr:iPort)。
总结;同一个内部地址(iAddr:iPort)只会映射相同的外部地址(eAddr:ePort);映射完成后;目标IP端口都无限制。
Address-Restricted cone NAT;内部客户端必须首先发送数据包到对方(IP=X.X.X.X);然后才能接收来自(IP=X.X.X.X)的数据包。在限制方面;唯一的要求是数据包是来自(IP=X.X.X.X)。内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort);所有发自(iAddr:iPort)的包都经由(eAddr:ePort)向外发送。外部主机(hostAddr:any)能通过给(eAddr:ePort)发包到达(iAddr:iPort)。注;any指外部主机源端口不受限制;只有发给NAT转换地址(eAddr:ePort)的数据包才被放行
总结;同一个内部地址(iAddr:iPort)只会映射相同的外部地址(eAddr:ePort);映射完成后;必须先发一个包给目标;然后才能收到目标回发的包;目标端口无限制。
Port-Restricted cone NAT;类似受限制锥形NAT(Restricted cone NAT);但是还有端口限制。一旦一个内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort);所有发自(iAddr:iPort)的包都经由(eAddr:ePort)向外发送。在受限圆锥型NAT基础上增加了外部主机源端口必须是固定的。
总结;同一个内部地址(iAddr:iPort)只会映射相同的外部地址(eAddr:ePort);映射完成后;必须先发一个包给目标(tAddr:tPort);然后才能收到目标(tAddr:tPort)回发的包;有目标端口限制。
Symmetric NAT;每一个来自相同内部IP与端口;到一个特定目的地地址和端口的请求;都映射到一个独特的外部IP地址和端口。同一内部IP与端口发到不同的目的地和端口的信息包;都使用不同的映射。只有曾经收到过内部主机数据的外部主机;才能够把数据包发回。
总结;同一个内部地址(iAddr:iPort)对不同目标(tAddr1:tPort1)(tAddr2:tPort2)会映射出不同的外部地址(eAddr1:ePort1)(eAddr2:ePort2);必须先发一个包给目标(iAddr:iPort)->(eAddr1:ePort1)->(tAddr1:tPort1);才能收到回发的包(tAddr1:tPort1)->(eAddr1:ePort1)->(iAddr:iPort1)。
NAT穿透;简单地讲就是要让处于不同NAT网络下的两个节点(Peer)建立直接连接;只知道自己的内网地址是肯定不行的;他们需要知道对方的公网IP和端口;然后双方互相向对方发送数据包;从而建立起连接。整个流程可以看做两个关键步骤;
其中;第二步;我们可以简单地通过一个第三方服务器来交换双方的IP和Port;但是第一步就比较困难;我们不妨根据不同类型的NAT的特点;分别看看在不同的NAT类型下;怎样才能拿到一个可供通讯的公网IP和Port。
注意;下面方案介绍时;都假设要通讯的双方处于同一NAT类型下;不同类型下的NAT穿透方案;我相信各位读者在理解各个方案之后;自然就能类推出来。
前面提过;完全锥形NAT下的节点(Client)只要建立起(iAddr:iPort)<->(eAddr:ePort)的映射关系之后;就能收到任何IP和端口发送的数据。所以基本思路如下;
受限圆锥形NAT获取自己公网地址的方式和上一步完全一致;但是因为受限圆锥形NAT需要先发送一个数据包之后才能收到目标传来的包。所以基本思路如下;
和受限圆锥形NAT完全一致。
因为对称型NAT对不同的目标(Server1)(Server2)会映射出不同的外网地址(eAddr1:ePort1)(eAddr2:ePort2);也就是说;我们通过前面用到的公网服务(Server1),获取的公网地址(eAddr1:ePort1);没办法共享给别人使用;他只能用来和(Server1)通讯。那我们不妨;将(Server1)作为一个代理;如果其他人想和(Client)进行通讯;可以通过(Server1)转发。基于这个思路;我们的做法如下;
理解了各个NAT类型下的解决简单方案之后;再来看STUN;TURN和ICE;你就会发现这三个协议负责的内容和上述的简单方案非常相似。
STUN;Session Traversal Utilities for NAT;NAT会话穿越应用程序;是一种网络协议;它允许位于NAT;或多重NAT;后的客户端找出自己的公网地址;查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创建UDP通信。 是不是感觉STUN干的活儿非常熟悉;没错;STUN负责的就是前面提到的Server1所做的内容。只不过STUN协议还具备另一个关键功能;就是确认Client的NAT类型;网络类型;。至于STUN是怎么获取Client公网地址这部分内容;我就不赘述了。接下来我会介绍一下STUN是如何确定Client的NAT类型;网络类型;的。
一旦路径通过红色箱子的终点时;UDP的直接沟通是没有可能性的。一旦通过黄色或是绿色的箱子;就有连线的可能。 上图中的大部分内容我相信各位童鞋应该都能看懂;其中关于;Public IP is link’s IP?;这一步我简单的讲一下;
TURN;全名Traversal Using Relay NAT;;是一种数据传输协议;data-transfer protocol;。允许在TCP或UDP的连接跨越NAT或防火墙。 TURN是一个client-server协议。TURN的NAT穿透方法与STUN类似;都是通过获取应用层中的公有地址达到NAT穿透。但实现TURN client的终端必须在通信开始前与TURN server进行交互;并要求TURN server产生;relay port;;也就是relayed-transport-address。这时TURN server会创建peer;即远程端点;remote endpoints;;开始进行中继;relay;的动作;TURN client利用relay port将数据发送至peer;再由peer转传到另一方的TURN client。
交互式连接创建;Interactive Connectivity Establishment;;一种综合性的NAT穿越的技术。 交互式连接创建是由IETF的MMUSIC工作组开发出来的一种Framework;可集成各种NAT穿透技术;如STUN、TURN;Traversal Using Relay NAT;中继NAT实现的穿透;、RSIP;Realm Specific IP;特定域IP;等。该framework可以让SIP的客户端利用各种NAT穿透方式打穿远程的防火墙。