NAT网络与内网穿透详解
大家有没有想过,为什么在公司里访问不了家里的电脑?这是因为IPv4地址有限,最大42亿个。为了更好的利用这有限的IP数量,网络分为局域网和广域网,将IP分为了私有IP和公网IP,一个局域网里的N多台机器都可以共用一个公网IP,从而大大增加了"可用IP数量"。收发数据就像收发快递,当我们需要发送网络包的时候,在IP层,需要填入源IP地址,和目的IP地址,也就是对应快递的发货地址和收货地址我们家里的局
文章目录
一、概述
1、简介
大家有没有想过,为什么在公司里访问不了家里的电脑?这是因为IPv4地址有限,最大42亿个。为了更好的利用这有限的IP数量,网络分为局域网和广域网,将IP分为了私有IP和公网IP,一个局域网里的N多台机器都可以共用一个公网IP,从而大大增加了"可用IP数量"。
收发数据就像收发快递,当我们需要发送网络包的时候,在IP层,需要填入源IP地址,和目的IP地址,也就是对应快递的发货地址和收货地址
2、NAT基本介绍
我们家里的局域网内,基本上都用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
,这叫SNAT(Source 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
, 这也叫DNAT
(Destination 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 访问内网服务。一波操作下来,就可以在公司的网络里访问家里的电脑。
更多推荐
所有评论(0)