关键字
stun协议\P2P\UDP打洞\NAT
常用方法
中继
使用中继服务器连接两台内网设备,受限于中继节点性能。
逆向连接
当客户端A、B之一有公网地址时可以使用该方法。
UDP打洞
最常见的方法
利用锥形NAT(下文将介绍NAT分类)会将 内网ip+端口 绑定一个 外网ip+端口 的特性实现。理论上来说,利用该特性就可以实现任意主机间的通信,但往往NAT会做很多限制,导致这种直接通信无法完成。下面以限制最多的 Restricted-Port NAT
为例说明:
网络拓扑图

Client A和B仅具有内网地址,有Restricted-Port NAT功能的router A和B将他们的内网地址及端口和外网地址及端口进行绑定,Server S具有外网地址。
限制前提
Restricted-Port NAT 会直接丢弃其他主机 主动
发送过来的报文,只有它向另一台主机发送一个报文后,它才会接收该主机发送过来的一个报文。所以即使A和B映射了公网地址也不能直接通信。
打洞过程
- Client A和B分别向S发送一条报文,S会记录下A和B的出口地址及端口(即:1.1.1.1:7777和2.2.2.2:8888)
- S分别向A和B返回对方的出口地址及端口
- A和B分别向对方的出口地址发送一个报文,由于Restricted-Port NAT的限制,该报文均会被丢弃。但同时,由于都向对方发送了报文,后面就能接收对方发送的报文。此时A和B就可以P2P通信了
NAT分类
基础NAT
只有主机本身就具有公网IP的情况下才能使用,此时基础NAT中会记录一张内网ip和公网ip的映射表
内网地址 | 外网地址 |
---|---|
192.168.1.111 | 1.1.1.1 |
192.168.1.222 | 2.2.2.2 |
192.168.1.333 | 3.3.3.3 |
NAPT
允许多个内网主机公用一个公网IP,通过端口区分,此时NAT中会记录如下映射(有时间限制,超时删除)
内网地址 | 外网地址 |
---|---|
192.168.1.111:1111 | 1.1.1.1:1111 |
192.168.1.222:1111 | 1.1.1.1:2222 |
192.168.1.333:5555 | 1.1.1.1:3333 |
完全锥型
内网地址+端口 和 外网地址+端口 一一绑定,不因访问资源地址变化而变化
出口地址可自由接收 任意外部主机的任意端口 发送来的报文
受限锥型
内网地址+端口 和 外网地址+端口 一一绑定,不因访问资源地址变化而变化
只有通过出口地址向另一台主机发送一个报文之后,才能接收该主机 任意端口 发送过来的报文。该主机直接发送的报文将被丢弃
端口受限锥型
内网地址+端口 和 外网地址+端口 一一绑定,不因访问资源地址变化而变化
只有通过出口地址向另一台主机 指定端口 发送一个报文之后,才能接收该主机 指定端口 发送过来的报文。该主机其他端口或其他主机发送的报文将被丢弃
对称型
需要访问的目标主机或端口不同,就会为该内网主机分配不同的外网ip+端口映射。这种类型的NAT很难进行p2p通信
NAT类型检测
如何知道内网设备使用的是哪一种NAT。
前提
两台具有公网ip的主机 S1和S2,一台处于内网的主机 Client,但不知道它的出口NAT类型
检测操作
- client向S1发送一个报文,S1收到报文后记录该报文的出口IP+端口并返回给client,client将S1返回的地址和自己本身的地址(例如使用ip addr命令获取)进行比较,如果相同,则client本身就使用的是公网地址,即NAT类型为
基础NAT
- client向S1和S2同时发送一个报文,S1和S2均返回其收到的报文出口地址,client对比它们返回的地址,如果不同,则使用的是
对称型NAT
- client向S2发送一个报文,S2将报文出口地址发送给S1,S1向该地址发送UDP报文,若client可以收到该报文,则使用的是
完全锥型NAT
- client向S1发送一个报文,S1获取到报文出口地址后,使用另一个端口向该地址发送一个报文,若client收到该报文,则使用的是
受限锥型NAT
- 其他则使用的是
端口受限NAT