NAT——网络穿透的四种模式
NAT 实现方式
- 静态转换
- 动态转换
- 端口多路复用
NAT 四种类型
- NAT1 完全圆锥型 (Full Cone)
- NAT2 受限锥型 (Restricted Cone)
- NAT3 端口限制圆锥型 (Port Restricted Cone)
- NAT4 对称型 (Symmetric)
NAT 特性
- 宽带分享
- 安全防护
常用穿透方法(UDP)
- STUN
- TURN
- LCE
- UPNP
优点
特定情况下可以减轻服务器的压力、节省公有合法 IP 地址、处理地址重叠。
缺点
延迟增大、配置和维护的复杂性、不支持某些应用或者服务,需要通过静态映射来避免。
静态转换
IP 地址的对应关系是一对一,而且是不变的,借助静态转换,能实现外部网络对内部网络中某些特设定服务器的访问。
举例:
公网 IP: 111.205.195.103 私网 IP: 192.168.1.66 NAT 网关: 192.168.1.1 端口: 80 (http)
映射前:访问 111.205.195.103:80 报错无法正常访问。
映射后:访问 111.205.195.103:80 信息传送到 192.168.1.66:80 端口,网站正常访问。
动态转换
IP 地址的对应关系是不确定的,而是随机的,所有被访问互联网的私有地址可随机转换为任何指定的合法的外部 IP 地址。
举例:
公网 IP 池: 111.205.195.103/24
端口多路复用
通过改变外出数据包的源 IP 地址和源端口并进行转换,内部网络的所有主机均可共享一个合法 IP 地址互联网的访问,节约 IP。
举例:
Client 192.168.1.5 NAT 210.21.12.140 Server1 210.15.27.166 Server2 210.15.27.140
NAT1 完全圆锥型 (Full Cone):来者不拒
初始状态时,Client 与 Server1、Client 与 Server2 都没有通讯过。
当 Client 通过 NAT 向 Server1 发送一个 packet 后,NAT 会生成如下映射:
Client 主机地址:端口 192.168.1.5:5000 NAT 公网地址:端口 210.21.12.140:8000
在全锥型网络下,后续当 Server1 要发送数据到 Client 时,Server1 首先将数据送到 NAT,NAT 接收到该报文,会将该报文转给 Client。

NAT2 受限圆锥型 (Restricted Cone):我不给你钥匙你不能进我家门
初始状态时,Client 与 Server1、Client 与 Server2 都没有通讯过。
当 Client 通过 NAT 向 Server1 发送一个 packet 后,NAT 中会生成如下映射:
Client 主机地址:端口 192.168.1.5:5000 NAT 公网地址:端口 210.21.12.140:8000
Server1 主机地址:端口 210.15.27.166
在受限圆锥型 NAT 下,Server1 要发送数据到 Client 时,Server1 首先将数据送到 NAT,NAT 接收到该报文,会将该报文转发给 Client。
但是 Server2 主机无法与 Client 主机进行通讯。因为 Client 从来没有和 Server2 通信过,NAT 将拒绝 Server2 试图与 Client 连接的动作。

NAT3 端口受限圆锥型 (Port Restricted Cone)
初始状态时,Client 与 Server1、Client 与 Server2 都没有通讯过。
当 Client 通过 NAT 向 Server1 发送一个 packet 后,NAT 中会生成如下映射:
Client 主机地址:端口 192.168.1.5:5000 NAT 公网地址:端口 210.21.12.140:8000
Server 主机地址:端口 210.15.27.166:80
在端口受限圆锥型 NAT 下,Server2 无法与 Client 通信,因为 Client 从来没有和 Server2 通信过。
并且 Server1 也只能用它的 210.15.27.166:80 与 Client 的 192.168.1.5:5000 通信,因为 Client 也从来没有和 Server1 的其他端口通信过。

NAT4 对称 NAT (Symmetric)
初始化状态时,Client 与 Server1、Client 与 Server2 都没有通信过。
当 Client 通过 NAT 向 Server1 发送一个 packet 后,NAT 中会生成如下映射:
Client 主机地址:端口 192.168.1.5:5000 NAT 公网地址:端口 210.21.12.140:8000
Server 主机地址:端口 210.15.27.166:80
接下来 Client 要使用相同的端口和 Server2 通信,将会在 NAT 中生成如下映射:
Client 192.168.1.5:5000 NAT 210.21.12.140:8000 Server1 210.15.27.166:80
Client 192.168.1.5:5000 NAT 210.21.12.140:8001 Server2 210.15.27.140:80
Server1 只能用它的 210.15.27.166:80 通过 NAT 的 210.21.12.140:8000 与 Client 的 192.168.1.5:5000 通信。
Server2 也只能用它的 210.15.27.140:80 通过 NAT 的 210.21.12.140:8001 与 Client 的 192.168.1.5:5000 通信。
Server1 或者 Server2 的其他端口则不能和 Client 的 192.168.1.5:5000 通信。

安全防护
STUN 定义
STUN (Session Traversal Utilities for NAT, NAT 会话穿越应用程序) 是一种网络协议,它允许位于 NAT(或多重 NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的 NAT 之后以及 NAT 为某一个本地端口所绑定的 Internet 端端口。这些信息被用来在两个同时处于 NAT 路由器之后的主机之间创建 UDP 通信。该协议由 RFC5389 定义。
STUN 穿透
STUNml (simple traversal of UDP over NAT) 的原理是通过某种机制预先得到内部私有 IP 地址对应在出口 NAT 上的对外公网 IP 地址,然后在报文负载中所描述的地址信息就直接填写出口 NAT 上的对外 IP 地址。其最大的优点是无需对现有 NAT / 防火墙设备做任何改动。局限性在于需要应用程序支持 STUN CLIENT 的功能,同时 STUN 并不适合支持 TCP 连接的穿越。
STUN 报文
消息头
所有的 STUN 消息都包含 20 个字头的消息头,包括 16 位的消息类型,16 位的消息长度和 128 位的事务 ID。
| 字段 | 说明 |
|---|---|
| 消息类型 | 16 位 |
| 消息长度 | 16 位,消息大小的字节数,但不包括 20 字节的头部 |
| 事务 ID | 128 位的标识符,用于随机请求和响应,请求与其相应的所有响应具有相同的标识符 |
消息许可类型
| 类型 | 说明 |
|---|---|
| 0x0001 | 捆绑请求 |
| 0x0101 | 捆绑响应 |
| 0x0111 | 捆绑错误响应 |
| 0x0002 | 共享私密请求 |
| 0x0102 | 共享私密响应 |
| 0x0112 | 共享私密错误响应 |
消息属性
消息头之后是 0 个或多个属性,每个属性进行 TLV 编码,包括 16 位的属性类型、16 位的属性长度和变长属性值。
| 字段 | 说明 |
|---|---|
| 属性类型 | 16 位 |
| 属性长度 | 16 位 |
| 属性值 | 变长属性值 |
属性类型定义
MAPPED-ADDRESS
MAPPED-ADDRESS 属性表示映射过的 IP 地址和端口。它包括 8 位的地址族,16 位的端口号及长度固定的 IP 地址。
RESPONSE-ADDRESS
RESPONSE-ADDRESS 属性表示响应的目的地址。
CHASNGE-REQUEST
客户使用 32 位的 CHANGE-REQUEST 属性来请求服务器使用不同的地址或端口号来发送响应。
SOURCE-ADDRESS
SOURCE-ADDRESS 属性出现在捆绑响应中,它表示服务器发送响应的源 IP 地址和端口。
CHANGED-ADDRESS
如果捆绑请求的 CHANGE-REQUEST 属性中的“改变 IP”和“改变端口”标志设置了,则 CHANGED-ADDRESS 属性表示响应发出的 IP 地址和端口号。
USERNAME
USERNAME 属性用于消息的完整性检查,用于消息完整性检查中标识共享私密。USERNAME 通常出现在共享私密响应中,与 PASSWORD 一起。当使用消息完整性检查时,可有选择地出现在捆绑请求中。
PASSWORD
PASSWORD 属性用在共享私密响应中,与 USERNAME 一起。PASSWORD 的值是变长的,用作共享私密,它的长度必须是 4 字节的倍数,以保证属性与边界对齐。
MESSAGE-INTEGRITY
MESSAGE-INTEGRITY 属性包含 STUN 消息的 HMAC-SHA1,它可以出现在捆绑请求或捆绑响应中;MESSAGE-INTEGRITY 属性必须是任何 STUN 消息的最后一个属性。它的内容决定了 HMAC 输入的 Key 值。
ERROR-CODE
ERROR-CODE 属性出现在捆绑错误响应或共享私密错误响应中。它的响应号数值范围从 100 到 699。
| 错误码 | 说明 |
|---|---|
| 400 | 错误请求:请求变形了。客户在修改先前的尝试前不应该重试该请求。 |
| 401 | 未授权:捆绑请求没有包含 MESSAGE-INTERITY 属性。 |
| 420 | 未知属性:服务器不认识请求中的强制属性。 |
| 430 | 过期资格:捆绑请求没有包含 MESSAGE-INTEGRITY 属性,但它使用过期的共享私密。客户应该获得新的共享私密并再次重试。 |
| 431 | 完整性检查失败:捆绑请求包含 MESSAGE-INTEGRITY 属性,但 HMAC 验证失败。这可能是潜在攻击的表现,或者客户端实现错误。 |
| 432 | 丢失用户名:捆绑请求包含 MESSAGE-INTEGRITY 属性,但没有 USERNAME 属性。完整性检查中两项都必须存在。 |
| 433 | 使用 TLS:共享私密请求已经通过 TLS(Transport Layer Security,即安全传输层协议)发送,但没有在 TLS 上收到。 |
| 500 | 服务器错误:服务器遇到临时错误,客户应该再次尝试。 |
| 600 | 全局失败:服务器拒绝完成请求,客户不应该重试。 |
TURN 穿透
TURN 即通过 Relay 方式穿越 NAT,也是私网中的 SIP 终端通过某种机制预先得剑 TURN Server 上的公网地址,私网终端发出的报文都要经过 TURN Server 进行 Relay 转发。这种方式除了具有 STUN 方式的优点外,还解决了 STUN 应用无法穿透对称 NAT (Symmetric NAT) 以及类似的 Firewall 设备的缺陷,局限性在于需要 SIP 终端支持 TURN Client,并增大了包的延迟和丢包的可能性。
TURN 定义
TURN(Traversal Using Relays around NAT,穿越 NAT 的中继)是一种网络协议,它提供了在对等主机之间传输数据的能力,而不需要确保它们都有一个公共 IP 地址。它由 RFC5766 定义,支持 UDP 和 TCP。
TURN 工作原理
一个需要连接的客户端通过一个 TURN 服务器来进行中继转发。首先,该客户端将数据发送到 TURN 服务器,TURN 服务器再将数据发送到目标客户端。接收数据时,目标客户端的 TCP 连接或者 UDP 连接是通过一个 TURN 服务器进行的。TURN 提供了一种确保可靠数据传输的方法,但在实现中可能会引入延迟。
TURN 与 STUN 的区别
- STUN 是允许客户端探测其在 NAT 下的 IP 地址,若没有公网 IP,可以通过 STUN 服务器来获取。是客户端与服务器之间的点对点协议;而 TURN 是需要一个中继服务,有点类似于 P2P 中的中继服务器,它负责转发数据。
- STUN 只是提供了 NAT 的公共 IP 地址,若在穿越时出现问题,无法解决。而 TURN 则会将所有数据通过中继服务器进行转发。
- TURN 服务器一般是需要付费的,STUN 服务器基本都是免费的。
UPNP 定义
UPnP (Universal Plug and Play,通用即插即用) 是一组网络协议,旨在使设备之间的连接、发现和通信变得简单。它由多个协议组成,允许设备自动发现并与网络中的其他设备进行通信。通过 UPnP,用户可以在家中的网络上轻松地连接和使用设备,如打印机、网络存储和其他设备。常用于媒体共享、游戏和家庭自动化。
UPNP 的工作原理
设备可以使用 UPnP 协议发现网络上的其他设备,并通过简单的命令进行控制和数据交换。当设备连接到网络时,它会向 UPnP 控制点发送消息,通知其存在和能力。控制点可以与这些设备进行通信,并发送命令以控制它们的功能。
UPNP 的优缺点
优点:方便、自动化的设备发现与配置、无缝连接设备。
缺点:安全隐患:UPnP 的安全性问题,可能导致网络受到攻击。