深入剖析 NAT 网络原理及内网穿透技术实现

什么是NAT?NAT的类型有哪些?

一、概述

图片

在我们家庭的局域网环境中,普遍采用192.168.xx.xx这类私有IP 。当我们发送网络数据包时,如果直接填写私有IP,就会产生一个问题:当对方回传数据包时,该如何确定目标?毕竟众多家庭都在使用诸如192.168.0.1这样的私有IP,网络无法直接判断应该将数据发送给谁。因此,必然需要将192.168.xx的私有IP转换为公有IP

一般来说,局域网内使用私有IP,而公网使用的是公有IP。当局域网中的私有IP想要访问局域网外的公有IP时,进行IP转换是必不可少的。那么,这个关键的转换过程究竟是在何处完成的呢?

答案是NAT设备,全称Network Address Translation,网络地址转换。基本上家用路由器都支持这功能。

二、NAT的工作原理

为便于理解,我们做个假设:假如你家境优渥,家中分配到一个公网IP地址 20.20.20.20 ,这个公网IP被配置到了你家具备NAT功能的家用路由器上。家中有众多需要联网的设备,像手机、电脑等,它们共同组建了一个局域网,使用的都是私有IP,例如常见的192.168.xx段。当你在电脑上执行ifconfig命令后,查询到家里这台电脑的IP地址为192.168.30.5 ,而你想要访问的公网IP地址是30.30.30.30

当你准备发送数据包时,你电脑的内核协议栈会构建一个IP数据包。在这个IP数据包的报头中,发送端的IP地址填写的是192.168.30.5,而接收端的IP地址则为30.30.30.30 。随后,这个数据包被发送至NAT路由器。

NAT路由器接收到数据包后,会对IP数据包中的源IP地址进行修改,将私有IP地址192.168.30.5替换为公网IP地址20.20.20.20 ,这一过程被称作SNATSource Network Address Translation,即源地址转换)。同时,NAT路由器会在其内部创建一条192.168.30.5 -> 20.20.20.20的映射记录,这条记录在后续流程中至关重要。此后,IP数据包通过公网中各个路由器的依次转发,最终成功抵达接收端30.30.30.30 ,至此,发送流程顺利结束。

当接收端完成数据处理,需要向你的电脑发送响应时,会把发送端IP地址设为自身的30.30.30.30,将接收端地址填写为你家的公网IP地址20.20.20.20 ,随后把数据包发往NAT路由器。

NAT路由器接收到来自公网的消息后,会立即查阅之前留存的映射信息。当发现其中有192.168.30.5 -> 20.20.20.20这条记录时,便会对这个数据包的目的IP地址进行修改,将其转换为内网IP地址192.168.30.5 ,这一操作被称为DNATDestination Network Address Translation,也就是目的地址转换)。完成转换后,NAT路由器会将数据包转发至你的电脑。

整个过程下来,NAT悄悄的改了IP数据包的发送和接收端IP地址,但对真正的发送方和接收方来说,他们却对这件事情,一无所知。这就是NAT的工作原理。

三、NAPT的原理

1、概述

至此,想必大家心中都存在一个很大的疑问。在局域网中,并非仅有一台机器,局域网内的每台机器在NAT下留下的映射信息都会是192.168.xx.xx -> 20.20.20.20 。在发送消息时,这样的映射或许不会产生问题,但当涉及到接收消息时,就难以确定该将响应回传给哪一台机器了。

这个问题十分关键且具有致命性,所以,在实际应用中,大多数情况下不会使用普通的NAT 。那么该如何解决呢?问题的根源在于我们无法区分内网中的多个网络连接。于是,我们可以引入其他信息来对内网中的各个网络连接加以区分,很容易便能想到端口

2、NAPT原理详解

IP数据包处于网络层,其本身并不包含端口信息。而常见的传输层协议,如TCP和UDP数据报文里才会有端口的相关信息 。

于是流程就变成了下面这样子。当你准备发送数据包的时候,你的电脑内核协议栈就会先构造一个TCP或者UDP数据报头,里面写入端口号,比如发送端口是5000,接收端口是3000,然后在这个基础上,加入 IP 数据报头,填入发送端和接收端的 IP 地址。那数据包长这样。

3、发送与接收过程

假设发送端的IP地址为192.168.30.5,端口号为5000接收端的IP地址是30.30.30.30,端口号为3000 。此时,发送端构造好数据包后,将其发往NAT路由器。

NAT路由器在接收到数据包后,会对IP数据包内的源IP地址和端口号进行修改。具体来说,就是把192.168.30.5:5000改写为20.20.20.20:6000 。同时,NAT路由器会在自身内部创建一条映射记录,即192.168.30.5:5000 -> 20.20.20.20:6000 。完成这些操作后,数据包会通过公网中各个路由器的接力转发,最终抵达接收端30.30.30.30:3000 ,至此,发送流程圆满结束。

当接收端进行响应时,会在数据包中填写发送端地址为30.30.30.30:3000接收端地址为20.20.20.20:6000,然后将数据包发往NAT路由器。

NAT路由器接收到数据包后,会查找自身之前留存的映射记录。当发现其中存在192.168.30.5:5000 -> 20.20.20.20:6000这条记录时,便会对数据包的目的IP地址和端口进行修改,将其还原为最初的192.168.30.5:5000 。完成修改后,NAT路由器就会把数据包转发到对应的电脑上。

如果局域网内有多个设备,他们就会映射到不同的公网端口上,毕竟端口最大可达 65535,完全够用。这样大家都可以相安无事。像这种同时转换 IP 和端口的技术,就是NAPT(Network Address Port Transfer , 网络地址端口转换 )。

4、ping命令

看到这里,问题就来了。那这么说**只有用到端口的网络协议才能被 NAT 识别出来并转发?但这怎么解释ping命令?ping基于 ICMP 协议,而 ICMP 协议报文里并不带端口信息。我依然可以正常的ping通公网机器并收到回包。

实际上,针对ICMP协议,NAT路由器进行了特殊处理。在ping报文头中有个Identifier信息,它本质上指的是发起ping命令的进程ID。对于NAT路由器而言,这个Identifier所发挥的作用与端口类似。

此外,当我们进行抓包操作时,会发现存在两个Identifier,一个后面标注BE(Big Endian),另一个标注LE(Little Endian) 。实际上,它们代表的是同一个数值,只是由于大小端存储方式不同,读取出来的值也有所差异。这就好比数字345,按照不同的字节顺序读取,可能会得到543。这种设计是为了兼容不同操作系统(例如Linux和Windows)在大小端处理上的差异,确保ICMP协议在不同系统环境下都能正常工作 。

四、内网穿透

1、概述

采用NAT方式上网时,其前提是内网机器主动向公网IP发起请求,如此NAT才能将内网的 IP端口转换为外网的 IP端口。反之,若公网机器想主动访问内网机器,会被NAT路由器拦截。这是因为NAT路由器没有相应的 IP端口映射记录,所以不会将数据转发给内网中的任何一台机器。

举个实际场景,你在家中的电脑上启动了一个HTTP服务,地址为192.168.30.5:5000,当你在公司办公室想用手机访问该服务时,会发现无法访问。那么,是否有办法让外网机器访问到内网服务呢?答案是肯定的。有句话说得好:“没有什么是加中间层不能解决的,如果有,那就再加一层”,这句话在此处同样适用。

本质上,由于NAT的存在,我们只能从内网主动发起连接,否则NAT设备不会记录对应的映射关系,没有映射关系也就无法转发数据。因此,我们可以在公网上部署一台服务器x,并对外暴露一个访问域名,然后让内网服务主动连接服务器x,这样NAT路由器上就会生成对应的映射关系。之后,所有用户都访问服务器x,服务器x将数据转发给内网机器,再将响应按原路返回,如此数据就能正常流通了,这就是内网穿透的原理。

对于上述的服务器x,你无需自行搭建,市面上已有许多现成的解决方案,付费使用即可,例如花生壳。

到这里,我们就可以回答这个问题:为什么我在公司里访问不了家里的电脑?那是因为家里的电脑在局域网内,局域网和广域网之间有个 NAT 路由器。由于 NAT 路由器的存在,外网服务无法主动连通局域网内的电脑。

2、两个内网的聊天软件如何建立通讯

我家机子是在我们小区的局域网里,班花家的机子也是在她们小区的局域网里。都在局域网里,且 NAT 只能从内网连到外网,那我电脑上登录的QQ是怎么和班花电脑里的QQ连上的呢?

上面这个问法其实是存在个误解,误以为两个 qq 客户端应用是直接建立连接的。然而实际上并不是,两个 qq 客户端之间还隔了一个服务器

也就是说,两个在内网的客户端登录 qq 时都会主动向公网的聊天服务器建立连接,这时两方的 NAT 路由器中都会记录有相应的映射关系。当在其中一个 qq 上发送消息时,数据会先到服务器,再通过服务器转发到另外一个客户端上。反过来也一样,通过这个方式让两台内网的机子进行数据传输。

3、两个内网的应用如何直接建立连接

对于两端通信的场景,例如 P2P 下载,该如何实现呢?实际上,这种情况仍需借助第三方服务器的协助。假设存在 A 和 B 两台处于局域网内的机子,A 所在内网对应的 NAT 设备为NAT_A,B 所在内网的 NAT 设备为NAT_B,此外还有一个第三方服务器server。具体流程如下:

  • 步骤 1 和 2:A 主动连接服务器server,此时NAT_A会记录下 A 的内网地址与外网地址的映射关系,同时server会获取 A 对应的外网 IP 地址和端口。
  • 步骤 3 和 4:B 进行与 A 相同的操作,主动连接第三方服务器serverNAT_B会记录 B 的内网地址和外网地址的映射关系server也会获取 B 对应的外网 IP 地址和端口。
  • 步骤 5、6 和 7:关键步骤来了。此时,server向 A 发送消息,要求 A 主动向 B 的外网 IP 地址和端口发送UDP消息。当NAT_B接收到 A 发送的 UDP 数据包时,根据NAT_B的配置差异,可能出现两种情况:一种是NAT_B能够直接将数据转发给 B,这样 A 和 B 就可以建立通信;另一种情况是通信失败,数据包被丢弃。不过,丢包并不影响整体流程,这一步的目的是NAT_A上创建关于 B 的映射关系
  • 步骤 8、9 和 10:与步骤 5 类似,server向 B 发送消息,要求 B 主动向 A 的外网 IP 地址和端口发送UDP消息。此时,NAT_B会记录关于 A 的映射关系。由于之前NAT_A已经记录了关于 B 的映射关系,NAT_A能够正常接收 B 的数据包并转发给 A。至此,A 和 B 可以正常进行数据通信,这就是所谓的 NAT 打洞
  • 步骤 11:需要注意的是,前面使用的是 UDP 数据包,目的是在两个局域网的 NAT 设备上打通通道。实际上,大多数应用使用的是 TCP 连接。因此,此时 A 需要主动向 B 发起 TCP 连接。完成这一步后,两端之间的通信就成功建立了。

这里可能有人会心生疑惑:端口已经被UDP使用了,若TCP再去使用,岂不是会出现端口重复占用(address already in use)的情况?实际上,这种情况并不会发生。端口重复占用的报错通常出现在两个TCP连接在未使用SO_REUSEADDR选项时,重复使用同一个IP端口。但UDP和TCP之间并不会出现这类报错。

之所以会出现端口重复占用的报错,主要是因为在Linux内核中,当内核接收网络数据时,会依据五元组(传输协议,源IP,目的IP,源端口,目的端口)来唯一确定数据的接收者。若两个连接的五元组完全一致,内核就无法判断该将数据发送给谁。而UDP和TCP的”传输协议”不同,这就导致它们的五元组也存在差异,所以不会出现上述端口重复占用的问题。

五、不同类型NAT详解

1 、简介

NAT分为两大类,基本的NAT和NAPT(即端口NAT,英文全称为Network Address/Port Translator)

2、基本NAT与 NAPT

基本的NAT(网络地址转换)包含静态NAT和动态NAT两种类型:

  • 静态转换(Static Nat):其原理是将内部网络的私有IP地址一对一地转换为公有IP地址,并且这种IP地址对的映射关系是固定不变的,即某个特定的私有IP地址始终转换为同一个指定的公有IP地址。
  • 动态转换(Dynamic Nat):动态转换的特点在于可以利用多个合法的外部地址集合。当把内部网络的私有IP地址转换为公用IP地址时,IP地址对并非固定,而是随机生成的,也就是说,私有IP地址能够随机地转换为指定地址集合内的任意一个IP地址。

NAPT(网络地址端口转换)则可进一步细分为锥型(Cone)和对称型(Symmetric) 两种模式:

  • 锥形NAT:举例来说,若client A使用内网的123端口与server A成功完成了通信,并且NAT设备将公网的456端口分配给了client A的123端口。那么当client A再次使用123端口向server B发起通信时,NAT设备依旧会将公网的456端口分配给client A的123端口。
  • 对称型NAT:同样假设client A使用内网的123端口与server A完成了通信,NAT设备将公网的456端口分配给了client A的123端口。此时,当client A想要向server B发起通信时,NAT设备不会再把公网的456端口分配给client A,而是可能会分配如789端口这样的其他端口给client A。
  • 简单概括非对称型NAT与对称型NAT的区别:对于非对称型NAT,其映射关系不受目的地址的影响,只要源地址相同,client内网的IP端口与NAT公网的IP端口之间的映射关系就保持一致;而对称型NAT的映射关系不仅与源地址有关,还与目的地址相关

3、锥型(Cone)NAT分类

锥型(Cone)NAT分类

锥形NAT还可以进一步细分为完全圆锥体(Full Cone NAT)受限制的圆锥体(Restricted Cone NAT)以及端口受限制的圆锥体NAT(Port Restricted Cone NAT) 这三种类型。

假设client A已经使用内网的123端口与server A完成了通信,并且NAT设备将公网的456端口分配给了client A的123端口。下面通过具体例子来阐述这三种锥型NAT的定义差异:

  • 完全圆锥体(Full Cone NAT):在这种模式下,server B的所有端口都能够直接通过公网的456端口与client A的123端口进行通信,server A的所有端口自然也不例外,对通信的IP地址和端口均没有限制
  • 受限制的圆锥体(Restricted Cone NAT):只有在client A已经向server B发送过消息的前提下,server B才可以通过公网的456端口与client A的123端口进行通信。满足这个条件后,server A和server B的所有端口数据都能够通过公网的456端口与client A的123端口进行交互,相比完全圆锥体NAT,增加了对IP地址的限制条件
  • 端口受限制的圆锥体NAT(Port Restricted Cone NAT):同样需要client A先向server B发送过消息,server B的X端口才能够通过公网的456端口与client A的123端口进行通信。需要注意的是,只有server A和server B的X端口可以与client A的123端口通信,其他端口若要与client A通信,则需要重新单独建立连接,在受限制圆锥体NAT的基础上,又增加了对端口的限制条件

值得一提的是,当client A使用这三种锥型NAT与server A、server B进行通信时,分配给client A的公网端口始终是456端口,不会发生改变

4、对称NAT概念的补充

假设有client A的123端口需要与server A的789端口、server B的789端口进行通信。在这种情况下,client A和server A若要实现通信,首先需要client A的123端口先向server A的789端口发送消息

并且当NAT设备为client A分配公网端口为456时,会存在以下限制:server A只能使用789端口与client A的123端口进行通信,server A的其他端口无法与client A通信;而server B若想要与client A通信,同样需要client A先向server B发送消息,并且此时分配给client A的公网端口不会是456。因此,在对称NAT模式下,实现端口的“打洞”操作相对比较困难。

5、总结

基本的NAT,它仅将内网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换,有动态与静态之区分。由于现在大部分都属于另一种类型,即NAPT,其中对称NAT打洞困难很高,但是安全性好;而锥型nat打洞比较容易。

NAT分类

实际上大部运营商提供的光猫上网服务都是锥形nat的而光纤入户,3g 4g网络,公共wifi登因为安全因素都是对称nat,另外目前绝大多数的路由器都是非对称型NAT(Cone NAT)。只要请求链接的对方是非端口限制锥型nat就都能实现打洞p2p链接的。只有双方都是对称是一定无法实现,或一方对称一方是端口限制锥型nat的情况也无法实现打洞。下面是各种类型打洞总结

发送端 接收端 能否打洞
完全锥形NAT 完全锥形NAT
完全锥形NAT IP限制性锥形NAT
完全锥形NAT 端口限制性锥形NAT
完全锥形NAT 对称式NAT
IP限制性锥形NAT IP限制性锥形NAT
IP限制性锥形NAT 端口限制性锥形NAT
IP限制性锥形NAT 对称式NAT
端口限制性锥形NAT 端口限制性锥形NAT
端口限制性锥形NAT 对称式NAT ×
对称式NAT 对称式NAT ×

六、家用网络低延迟方案

1、NAT简单回顾

NAT 主要有 4 种类型,分别为:NAT1、NAT2、NAT3、NAT4

  • NAT1: Full Cone NAT(全锥形NAT):这是最为宽松的网络环境,在这种模式下,无论是进行何种网络操作,基本上对 IP 地址和端口都没有限制,网络访问的自由度极高。
  • NAT2: Address-Restricted Cone NAT(受限锥型NAT):相较于 NAT1,NAT2 增加了地址方面的限制条件,即 IP 地址受限,不过端口方面仍然不受限制,网络访问的自由度有所降低。
  • NAT3: Port-Restricted Cone NAT(端口受限锥型NAT):与 NAT2 相比,NAT3 进一步增加了端口限制,也就是说,在这种模式下,IP 地址和端口都受到限制,网络访问的限制更为严格。
  • NAT4: Symmetric NAT(对称型NAT):对称型 NAT 具备端口受限锥型 NAT 的限制特性,当内部地址每一次向特定的外部地址发起请求时,都会绑定到一个新的端口。在这种类型的 NAT 模式下,基本无法实现 P2P 相关的网络操作。

从 NAT1 到 NAT4,网络限制程度逐渐递增。为了更好地满足多样化的网络需求,我们往往期望能够提升 NAT 类型。提升 NAT 类型具有诸多好处,比如在浏览网页时加载速度更快、观看视频更加流畅、游戏过程中响应更及时,下载速度也会更加稳定且快速。特别是对于游戏玩家而言,改善 NAT 类型后,联机速度会显著提升,游戏体验得到明显增强。

2、低延迟方案讲解

常言道:“想要游戏网速快,延迟低,就要 nat1,公网,桥接,unpn,硬件 nat 加速”。

  • 修改光猫工作模式: 将光猫的工作模式设置为桥接模式(此操作需要获取超级管理员的账号密码,很多情况下默认的账号密码就可以使用,你可以根据所在地区在网上搜索相关信息;如果是新款光猫,直接联系维修人员即可)。之所以要修改模式,是因为运营商通常默认将光猫设置为路由模式。判断光猫工作模式的方法为:如果无线路由器直接连接到光猫上就能够上网,那么此时光猫处于路由模式;而当无线路由器需要通过 PPPoE 拨号才能上网时,光猫则处于桥接模式。
  • 更改路由器设置: 启用无线路由器的 uPnP 功能(目前,大部分路由器都支持该功能)。将需要提升 NAT 类型的主机 IP 设置为静态 IP,然后开启 DMZ 功能(若通过路由器进行拨号,建议对路由器进行刷机操作,之后选择 NAT1 模式)。

3、总结

  • 路由器的层级数量越少,越有较大的可能性获得 NAT1 和 NAT2 类型的网络环境。
  • NAT1 是最为宽松的网络环境,几乎不存在限制条件;而 NAT4 是最严格的网络环境,在这种环境下,可能会出现无法玩游戏、P2P 下载没有速度等问题。
  • 如果光猫处于桥接模式,并且路由器通过拨号上网,那么网络类型有可能是 NAT2 和 NAT3,这种情况下,对于日常上网、游戏以及下载等操作,基本不会存在太多限制。
  • 通过拨号方式能够获得公网 IP 的网络环境,有机会优化到 NAT1 类型;而通过拨号获得内网 IP 的网络环境,基本属于 NAT4 类型。
  • 中国电信、中国联通提供的宽带网络一般分配的是公网 IP,而中国移动、中国广电、长城宽带等运营商提供的网络基本为内网 IP。这是因为中国移动的公网 IP 池相对其他运营商较小,所以通常采用对称型 NAT(这种方式可以节约公网 IP 资源,因为在断开连接时就会解绑映射关系,但绑定关系的建立和解除会消耗 CPU 性能,这也是为什么使用移动网络玩游戏时会时不时出现跳 ping 的现象)。

七、总结

  • 在IPv4地址资源有限的情况下,借助NAT路由器,整个内网中众多的机器对外仅需使用一个公网IP,极大程度地节省了IP资源,有效缓解了IPv4地址短缺的问题。
  • 当内网机子主动连接公网IP时,处于中间环节的NAT会将内网机子的内网IP转换为公网IP ,进而搭建起内网与外网之间的数据交互桥梁,实现了不同网络区域之间的信息流通。
  • 普通的NAT技术仅对网络包中的发送端和接收端IP地址进行修改,然而,当内网设备数量众多时,这种方式极有可能引发IP地址冲突的问题。所以,在实际应用中,通常会采用NAPT技术,该技术不仅会修改发送端和接收端的IP地址,还会对端口进行相应调整,从而有效避免了潜在的冲突,保障了网络通信的稳定性。
  • 由于NAT的作用机制,公网IP无法直接访问内网服务。不过,通过内网穿透技术,这一难题得以解决,使得公网IP能够访问内网服务。如此一来,用户便可以在公司网络环境下便捷地访问家中的电脑,实现了跨网络区域的设备访问与资源共享。

文章来源: https://study.disign.me/article/202508/22.nat-network-penetration-explained.md

发布时间: 2025-02-23

作者: 技术书栈编辑