NAT
NAT(Network Address Translation)技术是一种网络协议技术,它主要用于将私有网络中的IP地址转换为公共网络中的IP地址,以实现私有网络与公共网络之间的通信。NAT技术的主要作用是解决IPv4地址不足的问题。NAT技术可以提高网络的安全性,因为它隐藏了私有网络中的设备信息,使得公共网络无法直接访问这些设备。同时,NAT技术也可以帮助解决IP地址冲突的问题,因为私有网络中的设备可以使用相同的公网IP地址,而只需在与公共网络连接时进行地址转换。
NAT类型
根据端口映射方式,NAT可分为如下4类,前3种NAT类型可统称为cone类型。
(1)全克隆( Full Cone) : NAT把所有来自相同内部IP地址和端口的请求映射到相同的外部IP地址和端口。任何一个外部主机均可通过该映射发送IP包到该内部主机。
(2)限制性克隆(Restricted Cone) : NAT把所有来自相同内部IP地址和端口的请求映射到相同的外部IP地址和端口。但是,只有当内部主机先给IP地址为X的外部主机发送IP包,该外部主机才能向该内部主机发送IP包。
(3)端口限制性克隆( Port Restricted Cone) :端口限制性克隆与限制性克隆类似,只是多了端口号的限制,即只有内部主机先向IP地址为X,端口号为P的外部主机发送1个IP包,该外部主机才能够把源端口号为P的IP包发送给该内部主机。
(4)对称式NAT ( Symmetric NAT) :这种类型的NAT与上述3种类型的不同,对称NAT不使用一致的端口映射,所以当同一内部主机与不同外部(IP:端口)主机进行通信时, NAT会为每个新的会话分配一个新的端口号。其过滤规则也几乎总是端口限制(只允许从你联系的具体目的地返回流量)。
一般只有前三种类型可以打洞。
公网地址和端口的测试
本人通过代码测试在云主机和本地环境进行测试。客户端使用socket每次向云主机建立tcp或者udp连接,云主机就会打印客户端地址。并且客户端自身也会打印本地的地址和端口
- 发现每次客户端与服务器建立的tcp连接,新建tcp socket,连接云服务器,关闭tcp socket的过程,云主机显示客户端公网地址不变,但是端口发生了改变。本机的ip地址不变,分配的端口发生了改变
- 使用多个tcp socket与多个外部地址建立连接,公网ip不变,端口发送改变。本地主机分配的端口也发生改变。
- 客户端与云主机使用udp连接,建立udp socket,使用这个udp socket向服务端多次发送消息,其公网地址和端口都不会发送改变。或者给其他的外部地址消息,其公网ip与端口都不会发生改变。本机的端口和地址也不会改变。如果关闭udp socket,再新建udp socket,再发送消息,就会导致公网端口改变。本机的端口也会改变
打洞的原理
根据NAT类型可以知道,NAT网关对于不请自来的发到内网设备的数据包会丢弃。而如果内网的设备主动向外部地址发送数据包,之后这个外部地址就可以发送到内网设备。就相当于打了一个洞,通知NAT网关信任这个外部地址。
如何让一个私网内的设备和其他私网内的设备进行直连,就需要借助一个具有公网ip的服务器S来协助打洞过程。
UDP打洞
我经过公网地址和端口的测试。udp可以使用同样的地址和端口发送给其他地址,所以udp打洞很简单,原理就是
客户端A向服务器S不停的发送UDP数据包,S记录A的公网地址和端口
客户端B向服务器S不停的发送UDP数据包,S记录B的公网地址和端口
服务器S将B的公网地址和端口发送给A,将A的公网地址和端口发送给B
A开始向B的公网地址端口发送任意UDP消息,这样就在A的NAT网关上打了一个洞。B开始向A的公网地址端口发送任意UDP消息,这样就在B的NAT网关上打了一个洞。
之后A和B再发送消息就可以进行正常的UDP通信了。
TCP打洞
TCP打洞的难度比UDP高一个数量级,原因在于:
- TCP是有状态的 —— NAT必须看到完整的三次握手,否则不转发数据。
- TCP端口复用的限制 —— 操作系统通常不允许两个socket绑定同一个端口(除非设置SO_REUSEPORT)。
- AT对TCP的清洗更严格 —— 很多NAT会拦截非SYN的TCP包,或者强制校验TCP序列号。
本人没有测试成功,我使用一个socket与服务端建立连接,使用新的socket建立与客户端的连接,此时自己的不仅主机端口会改变,而且公网端口更会改变,而这个新的通信端口服务器不可能知道,对方客户端更不可能知道,所以与对方打洞是不可能成功的。
IPV6将代替IPV4
现在IPV6技术普遍。安装网络按照规定都是开启IPV6支持的,会更容易实现用户直连。