NAT 的原理是什么?
什么是 NAT
NAT (Network Address Translation, 网络地址转换) 是一个函数,能够将一个 IP 地址转换为另一个 IP 地址。
NAPT (Network Address/Port Translation,网络地址端口转换) 是我们通常真正所指的 NAT,能够将一个 (地址,端口) 二元组转换为另一个 (地址,端口) 二元组。
NAPT 的类型
为了更高效地理解,我举一个例子。假设在客户端看来,有如下三个连接:
192.168.0.106:1414 <-> 6.7.8.9:8000
192.168.0.106:3210 <-> 8.8.8.8:53
192.168.0.106:3210 <-> 1.1.1.1:66
每个连接可以看作一个四元组:
<src_addr, src_port, dest_addr, dest_port>
那么由于 Client 位于局域网中,Server A/B/C 是无法直接与之通信的。需要借助网关来通信。
对于 Client 而言,网关是透明的,也即 Client 会认为自己直接连接了 Server
简单而言,网关可以理解为一个拥有公网 IP 的转发者。它负责将 Client 发出或收到的数据重新封包,将其中的 Client IP:Port 替换为自己的 Gateway IP:Port.
此处不同的替换策略就对应了不同的 NAPT 类型。
对称型
对称 NAT 的特点是一一对应。从 Gateway 的视角来看,既然你 Client 与外界有三条连接,那么我就对这三条连接分别分配一个端口进行转发。其内部的转发规则表是这样的:
192.168.0.106:1414 <-> 221.21.12.2:4356 <-> 6.7.8.9:8000
192.168.0.106:3210 <-> 221.21.12.2:31234 <-> 8.8.8.8:53
192.168.0.106:3210 <-> 221.21.12.2:4324 <-> 1.1.1.1:66
锥形(不对称)
对称型的缺点是客户端有多少连接,我 Gateway 就要开多少端口。那不需要太多的 Client 就会耗尽我的端口。
有没有办法解决这个问题?其实我们可以把 Client 的 3210 端口的各个连接都当成一个连接。于是映射规则变成这样:
192.168.0.106:1414 <-> 221.21.12.2:4356 <-> 6.7.8.9:8000
192.168.0.106:3210 <-> 221.21.12.2:31234 <-> 8.8.8.8:53, 1.1.1.1:66
而基于安全策略,锥形又分为以下几种:
全锥型(Full Cone)
这是最为宽松的类型。只要 192.168.0.106:3210 <-> 221.21.12.2:31234
这条规则一建立,则任何外部消息均可通过 221.21.12.2:31234
转发给 192.168.0.106:3210
。比如上面的 8.8.8.8:53
,但并不止于此,假设突然来了个 233.233.233.233:233
向 221.21.12.2:31234
发送消息,那么 192.168.0.106:3210
都能收到。
简言之:可以不请自来。外面的机器比如 Host X (红色) 不需要和你打招呼,直接就能给 Client 发信息。因此安全性比较差。
受限锥型(Restricted Cone)
也称 IP 受限锥型,要求必须 Client 和外网的 Server IP 发起过连接,才能允许该 Server 向 Client 发送信息。比如上面的 Server A/B/C 可以,但 Host X (红色) 不行。
简言之:不能不请自来,必须 Client 主动先邀请。
端口受限锥型(Port Restricted Cone)
在受限锥形的基础上增加了端口限制,要求 <IP:Port>
均有过历史连接,才能连进来。