由于 ipv4 地址数量的有限性,导致实际网络部署模式中存在大量的 NAT 网络。对于 NAT 内部的主机,可以主动发起去公网的流量,但对于位于不同 NAT 内的两台主机而言,想要直接进行点对点的连接,就需要用到打洞技术了。
常见的 NAT 类型
-
完全锥型(Full Cone NAT):在完全锥型NAT中,一个内部IP地址和端口的组合在转换为公共IP地址和端口后,可以与任何外部主机进行通信。同时,外部主机可以通过任何地址和端口向内部主机发送数据。这种类型的NAT不限制内部主机与外部主机的通信,因此具有最大的灵活性。
-
受限锥型(Restricted Cone NAT):在受限锥型NAT中,一个内部IP地址和端口的组合在转换为公共IP地址和端口后,只能与一个特定的外部主机进行通信。这个外部主机是在内部主机首次向其发送数据时确定的,之后只有来自这个外部主机的数据才会被NAT转发给内部主机。其他外部主机无法与内部主机直接通信。
-
端口受限锥型(Port Restricted Cone NAT):与受限锥型类似,但还限制了端口号。
-
对称型(Symmetric NAT):在对称型NAT中,一个内部IP地址和端口的组合在转换为公共IP地址和端口后,只能与一个特定的外部主机进行通信。与受限锥型NAT不同的是,这个特定的外部主机是根据内部主机与外部主机之间的通信请求动态选择的,每次与不同外部主机通信时,NAT都会分配一个新的公共IP地址和端口。
对称NAT是一个请求对应一个端口,非对称NAT是多个请求对应一个端口,所以像锥型。
STUN
STUN(Session Traversal Utilities for NAT)是一种基于网络协议的技术,用于解决网络中的NAT(Network Address Translation)问题。STUN协议允许设备在NAT后面找到可用的公共IP地址和端口,以建立点对点连接。它通过一个称为STUN服务器的中间节点来实现。设备首先向STUN服务器发送请求,服务器会在响应中返回设备的公共IP地址和端口。设备可以将这些信息用于直接通信,而无需通过NAT。
STUN协议可以用于多种应用场景,例如实时通信(如VoIP电话、视频聊天)和P2P文件共享等。它为设备提供了一种机制,可以绕过NAT并建立直接的点对点连接,从而提高通信的效率和质量。
STUN 打洞流程
参考官方文档可以很清楚的看懂整个打洞的流程:
RFC 3489 - STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)):
+--------+
| Test |
| I |
+--------+
|
|
V
/\ /\
N / \ Y / \ Y +--------+
UDP <-------/Resp\--------->/ IP \------------->| Test |
Blocked \ ? / \Same/ | II |
\ / \? / +--------+
\/ \/ |
| N |
| V
V /\
+--------+ Sym. N / \
| Test | UDP <---/Resp\
| II | Firewall \ ? /
+--------+ \ /
| \/
V |Y
/\ /\ |
Symmetric N / \ +--------+ N / \ V
NAT <--- / IP \<-----| Test |<--- /Resp\ Open
\Same/ | I | \ ? / Internet
\? / +--------+ \ /
\/ \/
| |Y
| |
| V
| Full
| Cone
V /\
+--------+ / \ Y
| Test |------>/Resp\---->Restricted
| III | \ ? /
+--------+ \ /
\/
|N
| Port
+------>Restricted
Figure 2: Flow for type discovery process
附
打洞客户端:GitHub - ccding/go-stun: A go implementation of the STUN client (RFC 3489 and RFC 5389)
公用stun服务器:公用 Stun 服务器列表 - FreeSWITCH-CN中文社区