NAT网络与内网穿透详解

2/4/2024 5:40:54 PM
1464
0

一、概述

我们家里的局域网内,基本上都用192.168.xx.xx这样的私有IP,如果我们在发送网络包的时候,这么填。对方在回数据包的时候该怎么回?毕竟千家万户人用的都是192.168.0.1,网络怎么知道该发给谁?所以肯定需要将这个192.168.xx私有IP转换成公有IP
局域网内用的是私有IP,公网用的都是公有IP。一个局域网里的私有IP想访问局域网外的公有IP,必然要做个IP转换,这是在哪里做的转换呢?

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

二、NAT的工作原理

为了简单,我们假设你很富,你家里分到了一个公网 IP 地址 20.20.20.20,对应配到了你家自带 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悄悄的改了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接收端IP地址就是30.30.30.30。将数据包发到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。之后将其转发给你的电脑上。

如果局域网内有多个设备,他们就会映射到不同的公网端口上,毕竟端口最大可达 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)下大小端不同的情况。

四、内网穿透

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。流程如下。

  • step1和2: A 主动去连 server,此时 A 对应的NAT_A就会留下 A 的内网地址和外网地址的映射关系,server 也拿到了 A 对应的外网 IP 地址和端口。
  • step3和4: B 的操作和 A 一样,主动连第三方 server,NAT_B内留下 B 的内网地址和外网地址的映射关系,然后 server 也拿到了 B 对应的外网 IP 地址和端口。
  • step5和step6以及step7: 重点来了。此时 server 发消息给 A,让 A 主动发UDP消息到 B 的外网 IP 地址和端口。此时 NAT_B 收到这个 A 的UDP数据包时,这时候根据 NAT_B 的设置不同,导致这时候有可能 NAT_B 能直接转发数据到 B,那此时 A 和 B 就通了。但也有可能不通,直接丢包,不过丢包没关系,这个操作的目的是给 NAT_A 上留下有关 B 的映射关系
  • step8和step9以及step10: 跟step5一样熟悉的配方,此时 server 再发消息给 B,让 B 主动发UDP消息到 A 的外网 IP 地址和端口。NAT_B 上也留下了关于 A 的映射关系,这时候由于之前 NAT_A 上有过关于 B 的映射关系,此时 NAT_A 就能正常接受 B 的数据包,并将其转发给 A。到这里 A 和 B 就能正常进行数据通信了。这就是所谓的 NAT 打洞
  • step11: 注意,之前我们都是用的 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 port与server A完成通信,并且NAT将公网的456 port分配给client A的123 port,此时若client A再用123 port向server B发起通信,则NAT仍然会将公网的456 port分给client A的123 port
  • 对于对称型NAT,仍然假设已经有client A用内网的123 port与server A完成通信,并且NAT将公网的456 port分配给client A的123 port,此时若client A想向server B发起通信,则NAT就不会在将公网的456 port分给client A,比如会将789 port分配给client A
  • 对于非对称型NAT与对称型NAT的区别概括为一句话就是:对于非对称型NAT,映射关系与目的地址无关, 只要源地址相同,client内网IP端口与NAT公网IP端口映射关系就相同;而对称的NAT,映射关系还与目的地址有关

3、锥型(Cone)NAT分类

锥形NAT又可分为:完全圆锥体(Full Cone NAT)受限制的圆锥体(Restricted Cone NAT)端口受限制的圆锥体NAT(Port Restricted Cone NAT)三种

假设 client A 已经用内网的 123 port 与 server A 完成通信,并且 NAT 将公网的 456 port 分配给 client A 的 123 port,下面举例说明三种锥型NAT定义区别:

  • 完全圆锥体(Full Cone NAT):server B的所有端口都可以直接通过公网的 456 port 与 client A的123 port通信,当然也包括 server A的所有端口
    (对IP、port没有限制)
  • 受限制的圆锥体(Restricted Cone NAT):需要client A已经向server B发送过消息,server B才能够通过公网的 456 port 与 client A 的 123 port 通信,在此前提下,server A、server B的所有端口数据都可以通过公网的 456 port与client A的123 port通信
    (在完全圆锥基础上加了对IP的限制)
  • 端口受限制的圆锥体NAT(Port Restricted Cone NAT):需要client A已经向server B发送过消息,server B的X端口才能通过公网的 456 port 与 client A的123 port通信,注意只有server A、server B的X端口才能与client A的123 port通信,其他端口若想与client A通信需要再单独建立连接
    (在受限制圆锥基础上加了对port的限制)

client A在使用这三种锥型NAT与server A、server B通信时,分配给client A的公网一直是456 port,不会变

4、对称NAT概念的补充

假设有client A的123 port与server A的789 port、server B的789 port,若client A、server A想通信需要:client A的123先向server A的789发送消息

并且分配给client A公网port 为456,则有:server A只能使用789与clientA的123通信,server A的其他端口不能与client A通信;server B若想与client A通信,需要client A先向server B发送消息,并且分配给client A的公网的port不会是456,故打洞困难

5、总结

基本的NAT,它仅将内网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换,有动态与静态之区分。由于现在大部分都属于另一种类型,即NAPT,其中对称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,端口受限锥型,相比NAT2,NAT3 增加了端口限制,即IP、端口都受限
  • NAT4: Symmetric NAT,对称型NAT,对称型NAT具有端口受限锥型的受限特性,内部地址每一次请求一个特定的外部地址,都会绑定到一个新的端口。这种类型基本上就告别P2P了

从NAT1到NAT4限制越来越多,为了满足各种需求,我们希望提升NAT类型。提升NAT类型的好处有,浏览网页、观看视频、游戏等更顺畅,下载速度更稳定快速,特别是对那些玩游戏的,提升改善NAT类型后联机速度更快,游戏体验明显提高

2、低延迟方案讲解

想要游戏网速快,延迟低,就要nat1,公网,桥接,unpn,硬件nat加速

  • 修改光猫工作模式

把光猫工作模式设置为桥接模式(需要超级管理员账号密码,很多都是默认,可以根据地区上网搜索,新款的直接联系维修工人),修改模式,因为运营商一般默认设置光猫工作在路由模式。无线路由器直接连到猫上就可以上网的,那么光猫是路由模式。无线路由器需要PPPoE拨号上网的就是桥接模式

  • 更改路由器设置

启用无线路由器的uPnP功能,uPnP大部分路由器都支持。把要提升NAT类型的主机IP设置为静态,然后开启DMZ(通过路由器拨号,路由器最好要刷机,然后选择NAT1模式)

3、总结

  • 路由器层数越少,越可能得到NAT1和NAT2类型
  • NAT1是最宽松的网络环境,基本没限制。NAT4是最严格的网络环境,可能会玩不了游戏、P2P下载都没速度
  • 如果光猫是桥接模式,路由器拨号上网的有可能是NAT2和NAT3,对上网、游戏和下载都没有太多限制
  • 拨号能获得公网IP的,可以优化到NAT1,拨号获得内网IP基本是NAT4
  • 中国电信、中国联通宽带一般是公网IP,中国移动、中国广电、长宽等基本是内网IP。
    因为移动公网ip池比其他运营商少,所以一般都用对称型nat(节约公网ip,因为断开连接就会解绑映射,不过绑定关系的建立和解除会消耗cpu性能,所以移动打游戏时不时跳ping)

七、总结

  • IPV4 地址有限,但通过 NAT 路由器,可以使得整个内网 N 多台机器,对外只使用一个公网 IP,大大节省了 IP 资源
  • 内网机子主动连接公网 IP,中间的 NAT 会将内网机子的内网 IP 转换为公网 IP,从而实现内网和外网的数据交互
  • 普通的 NAT 技术,只会修改网络包中的发送端和接收端 IP 地址,当内网设备较多时,将有可能导致冲突。因此一般都会使用 NAPT 技术,同时修改发送端和接收端的 IP 地址和端口
  • 由于 NAT 的存在,公网 IP 是无法访问内网服务的,但通过内网穿透技术,就可以让公网 IP 访问内网服务。一波操作下来,就可以在公司的网络里访问家里的电脑。

本文原始链接: https://blog.csdn.net/lemon_TT/article/details/128846476

全部评论



提问