NAT反连穿透实战指南
网络编程关键配置建议:
- SO_REUSEADDR选项:用于解决服务端异常终止后的端口占用问题。该选项允许在TIME_WAIT状态期间重用本地地址,需在调用
bind()
函数之前设置。但需注意此选项无法解决”Cannot assign requested address”连接错误。 - SO_REUSEPORT选项:实现端口复用的高级机制,允许同一端口同时作为服务端监听端口和客户端源端口。该配置需在
bind()
操作完成后设置,否则会导致多个进程共享同一端口监听,违背设计初衷。 - 动态重绑定机制:服务端可在保持客户端连接的同时,重新建立监听端口,此操作不会影响现有客户端连接的正常通信。
- SO_BINDTODEVICE绑定限制:启用套接字设备绑定后,套接字将被强制关联至特定网络接口,导致本地回环地址(127.0.0.1)访问被阻断。此时必须显式指定目标网卡的实际IP地址才能建立连接,此特性在需要强制流量走特定网络路径的场景中尤为重要。
1 | /** |
非NAT 1状态下的外网可达性分析:
在上游单路由器场景下,最终NAT类型=路由器NAT策略∧WAN口网关NAT策略。例如:路由器NAT=3且WAN口为公网IP时,检测结果为NAT Type 3。
参考:https://help.onethingcloud.com/9dd6/e9ec, 部分路由器支持NAT类型调整(可设为NAT1),主流路由器均支持UPnP端口映射——WAN口为公网IP时,UPnp映射成功即可实现外网访问;若无UPnP功能,可启用DMZ将指定LAN设备暴露至外网。核心前提:WAN口需为公网IP或NAT Type 1,运营商级NAT限制为决定性因素。
如何检测WAN口NAT类型:
直接探测会叠加路由器NAT策略。精确检测方案:先将路由器设为NAT Type 1(消除本地策略干扰),再通过STUN协议探测——需预先用UPnP映射STUN所需的两组UDP端口,确保探测准确性。
NAT 1状态下,不配置UPnP端口映射能否实现外网访问?
不能。NAT Type 1虽具备公网可达性,但端口映射仍是必要前提。无显式端口映射规则时,NAT设备无法将外部请求转发至内网主机。UPnP IGD协议通过自动配置NAT映射规则,实现内网服务的外网暴露机制:客户端向NAT设备下发端口映射请求,NAT设备依据IGD规则建立内网IP:端口到公网IP:端口的转发映射,从而完成数据包的双向路由。
P2P穿透核心机制与NAT技术原理:
NAT(Network Address Translation)作为IPv4地址短缺的核心解决方案,通过地址转换实现内网主机与公网的通信。在虚拟化环境中,网络模式选择直接影响NAT行为:
- 桥接模式:虚拟机与宿主机处于同一二层网络,直接获取DHCP分配的公网/内网IP
- NAT模式:创建独立的虚拟网段,通过宿主机的NAT服务实现地址转换与路由
- 主机模式:构建仅包含宿主机与虚拟机的隔离网络,无外部路由能力
P2P穿透的本质是在NAT限制下建立端到端直连,通过STUN/TURN协议识别NAT类型并选择对应的穿透策略。
在IPv4地址资源枯竭的背景下,NAT(Network Address Translation)成为解决地址短缺的核心技术。当内网主机通过NAT网关与外部网络通信时,网关执行IP地址与端口的转换操作:外部服务器仅感知到NAT网关的公网地址,而非内网主机的真实私有地址,此过程即为NAT映射。
当知道这台电脑的外界ip和端口后,其他人就有可能来和你通信了,这里需要一台中间服务器,注意p2p并不是完全不需要第三方服务器,只是传输数据的时候不需要第三方服务器参与,是peer2peer端对端的,这些转换后的ip和端口需要第三方服务器来传达给其他人,其他人知道ip和端口就可以来连接你了。
当然,并不是知道ip和端口就一定能够连接得上了,路由器也有一定的策略来防范这些,这就是所说的nat类型,nat为1时,所有人都可以来连接,nat为2时,只有之前通信过的ip才可以来连接。
这里有一个比喻,假设nat网关就是女生宿舍的宿管阿姨,你要去803寝室给一个女生修电脑,如果nat为1,则你给宿管阿姨说要去803,她就让你去了,如果是nat为2,需要你是女生的家人(一系列的人)才能进去,如果nat为3,需要你是女生的男朋友(之前女生交代给阿姨过的)才能进去,如果nat为4,则好比这个女生有很多朋友,每个朋友都要有自己的口令才能进去。
NAT打洞原理:
受限锥型NAT打洞原理
主机A、B分别与服务器C建立连接,获取对方的公网地址。A向B的公网地址发送UDP包触发NAT A建立映射,同时通过C邀请B向A的公网地址回包。当B收到邀请后也向A发送UDP包触发NAT B建立映射,双方完成会话建立后即可直接通信。此类型仅要求源IP匹配,端口不限。端口受限锥型NAT打洞原理:
与受限锥型类似,但需同时匹配源IP和端口,只能使用已建立映射的外部Tuple进行通信。
对称型NAT穿透方式(4只能和1,2打洞):
- 同时开放TCP(SimultaneousTCP open)策略
如果 Client A-1和 Client B-1能够彼此正确的预知对方的NAT将会给下一个TCP连接分配的公网TCP端口,并且两个客户端能够同时地发起一个面向对方的“外出”的TCP连接请求,并在对方的 SYN 包到达之前,自己刚发送出去的SYN包都能顺利的穿过自己的NAT的话,一条端对端的TCP连接就能成功地建立了。
问题:时钟严格一致,很难做到。 - UDP端口猜测策略
通常,对称NAT分配端口有两种策略,一种是按顺序增加,一种是随机分配。如果这里对称NAT使用顺序增加策略,那么,ClientB-1将两次被分配的Tuples发送给Server后,Server就可以通知ClientA-1在这个端口范围内猜测刚才ClientB-1发送给它的socket-1中被NAT映射后的Tuples,ClientA-1很有可能在有效期内成功猜测到端口号,从而和ClientB-1成功通信。
问题:不能为随机分配端口的对称型NAT打洞。
为啥nat4只能和nat1/2通信:
突然想明白为啥nat4只能和nat1/2通信了,对于nat4:内网主机每次访问不同的外网主机时,都会生成一个新的洞(我测试,访问同一个外网主机,外部端口也会变)。而前面3种类型(nat1/2/3)使用的是同一个洞。所以nat4哪怕洞打成功了,后续真正发起请求时外部端口(对于对端来说是源端口)可能就变了,如果对端是也是nat3/4,源端口变了,就请求不上了,而如果是nat1/2,源端口变了也没关系。
扩展:当两端路由器的NAT类型是(端口限制锥型,对称型)或者(对称型,对称型)时,使用STUN协议就无法穿越,这个时候就需要使用TURN协议。TURN协议简单来说就是进行数据转发,两个内网主机分别把内容发给TURN服务器,TURN服务器再将内容分别转发给对端,以此来实现通信。