我们家里的局域网内,基本上都用192.168.xx.xx
这样的私有IP,如果我们在发送网络包的时候,这么填。对方在回数据包的时候该怎么回?毕竟千家万户人用的都是192.168.0.1
,网络怎么知道该发给谁?所以肯定需要将这个192.168.xx
私有IP转换成公有IP。
局域网内用的是私有IP,公网用的都是公有IP。一个局域网里的私有IP想访问局域网外的公有IP,必然要做个IP转换,这是在哪里做的转换呢?
答案是NAT设备,全称Network Address Translation,网络地址转换。基本上家用路由器都支持这功能。
为了简单,我们假设你很富,你家里分到了一个公网 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的工作原理。
到这里,相信大家都有一个很大的疑问。局域网里并不只有一台机器,局域网内每台机器都在 NAT 下留下的映射信息都会是 192.168.xx.xx -> 20.20.20.20
,发送消息是没啥事,但接收消息的时候就不知道该回给谁了。
这问题相当致命,因此实际上大部分时候不会使用普通的 NAT。那怎么办呢?问题出在我们没办法区分内网里的多个网络连接。于是乎。我们可以加入其他信息去区分内网里的各个网络连接,很自然就能想到端口。
IP数据包(网络层)本身是没有端口信息的。常见的传输层协议TCP和UDP数据报文里才有端口的信息
于是流程就变成了下面这样子。当你准备发送数据包的时候,你的电脑内核协议栈就会先构造一个TCP或者UDP数据报头,里面写入端口号,比如发送端口是5000
,接收端口是3000
,然后在这个基础上,加入 IP 数据报头,填入发送端和接收端的 IP 地址。那数据包长这样。
假设,发送端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 , 网络地址端口转换 )。
看到这里,问题就来了。那这么说只有用到端口的网络协议才能被 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)下大小端不同的情况。
使用了NAT上网的话,前提得内网机器主动请求公网 IP,这样NAT才能将内网的 IP 端口转成外网 IP 端口。反过来公网的机器想主动请求内网机器,就会被拦在 NAT 路由器上,此时由于 NAT 路由器并没有任何相关的 IP 端口的映射记录,因此也就不会转发数据给内网里的任何一台机器。举个现实中的场景就是,你在你家里的电脑上启动了一个 HTTP 服务,地址是192.168.30.5:5000,此时你在公司办公室里想通过手机去访问一下,却发现访问不了。那问题就来了,有没有办法让外网机器访问到内网的服务?有。大家应该听过一句话叫,“没有什么是加中间层不能解决的,如果有,那就再加一层”。放在这里,依然适用。
说到底,因为 NAT 的存在,我们只能从内网主动发起连接,否则 NAT 设备不会记录相应的映射关系,没有映射关系也就不能转发数据。所以我们就在公网上加一台服务器 x,并暴露一个访问域名,再让内网的服务主动连接服务器 x,这样NAT路由器上就有对应的映射关系。接着,所有人都去访问服务器x,服务器x将数据转发给内网机器,再原路返回响应,这样数据就都通了。这就是所谓的内网穿透。
像上面提到的服务器x,你也不需要自己去搭,已经有很多现成的方案,花钱就完事了,比如花某壳。
到这里,我们就可以回答这个问题:为什么我在公司里访问不了家里的电脑?那是因为家里的电脑在局域网内,局域网和广域网之间有个 NAT 路由器。由于 NAT 路由器的存在,外网服务无法主动连通局域网内的电脑。
我家机子是在我们小区的局域网里,班花家的机子也是在她们小区的局域网里。都在局域网里,且 NAT 只能从内网连到外网,那我电脑上登录的QQ是怎么和班花电脑里的QQ连上的呢?
上面这个问法其实是存在个误解,误以为两个 qq 客户端应用是直接建立连接的。然而实际上并不是,两个 qq 客户端之间还隔了一个服务器
也就是说,两个在内网的客户端登录 qq 时都会主动向公网的聊天服务器建立连接,这时两方的 NAT 路由器中都会记录有相应的映射关系。当在其中一个 qq 上发送消息时,数据会先到服务器,再通过服务器转发到另外一个客户端上。反过来也一样,通过这个方式让两台内网的机子进行数据传输。
两端通信,比如 P2P 下载,这种该怎么办呢?这种情况下,其实也还是离不开第三方服务器的帮助。假设还是 A 和 B 两个局域网内的机子,A内网对应的NAT设备叫NAT_A
,B内网里的NAT设备叫NAT_B
,和一个第三方服务器server
。流程如下。
NAT_A
就会留下 A 的内网地址和外网地址的映射关系,server 也拿到了 A 对应的外网 IP 地址和端口。NAT_B
内留下 B 的内网地址和外网地址的映射关系,然后 server 也拿到了 B 对应的外网 IP 地址和端口。UDP
消息到 B 的外网 IP 地址和端口。此时 NAT_B 收到这个 A 的UDP数据包时,这时候根据 NAT_B 的设置不同,导致这时候有可能 NAT_B 能直接转发数据到 B,那此时 A 和 B 就通了。但也有可能不通,直接丢包,不过丢包没关系,这个操作的目的是给 NAT_A 上留下有关 B 的映射关系。UDP
消息到 A 的外网 IP 地址和端口。NAT_B 上也留下了关于 A 的映射关系,这时候由于之前 NAT_A 上有过关于 B 的映射关系,此时 NAT_A 就能正常接受 B 的数据包,并将其转发给 A。到这里 A 和 B 就能正常进行数据通信了。这就是所谓的 NAT 打洞。SO_REUSEADDR
的情况下,重复使用了某个IP端口。而UDP和TCP之间却不会报这个错。之所以会有这个错,主要是因为在一个linux内核中,内核收到网络数据时,会通过五元组(传输协议,源IP,目的IP,源端口,目的端口
)去唯一确定数据接受者。当五元组都一模一样的时候,内核就不知道该把数据发给谁。而UDP和TCP之间"传输协议"不同,因此五元组也不同,所以也就不会有上面的问题。
NAT分为两大类,基本的NAT和NAPT(即端口NAT,英文全称为Network Address/Port Translator)
基本NAT分为静态NAT、动态NAT:
NAPT又分为锥型(Cone)和对称型(Symmetric):
锥形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定义区别:
client A在使用这三种锥型NAT与server A、server B通信时,分配给client A的公网一直是456 port,不会变
假设有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,故打洞困难
基本的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 | × |
NAT有4个类型,它们分别是:NAT1、NAT2、NAT3、NAT4
从NAT1到NAT4限制越来越多,为了满足各种需求,我们希望提升NAT类型。提升NAT类型的好处有,浏览网页、观看视频、游戏等更顺畅,下载速度更稳定快速,特别是对那些玩游戏的,提升改善NAT类型后联机速度更快,游戏体验明显提高
想要游戏网速快,延迟低,就要nat1,公网,桥接,unpn,硬件nat加速
把光猫工作模式设置为桥接模式(需要超级管理员账号密码,很多都是默认,可以根据地区上网搜索,新款的直接联系维修工人),修改模式,因为运营商一般默认设置光猫工作在路由模式。无线路由器直接连到猫上就可以上网的,那么光猫是路由模式。无线路由器需要PPPoE拨号上网的就是桥接模式。
启用无线路由器的uPnP功能,uPnP大部分路由器都支持。把要提升NAT类型的主机IP设置为静态,然后开启DMZ(通过路由器拨号,路由器最好要刷机,然后选择NAT1模式)
本文原始链接: https://blog.csdn.net/lemon_TT/article/details/128846476
本文链接:https://blog.nnwk.net/article/1525
有问题请留言。版权所有,转载请在显眼位置处保留文章出处,并留下原文连接
Leave your question and I'll get back to you as soon as I see it. All rights reserved. Please keep the source and links
友情链接:
子卿全栈
全部评论