NAT,私网IP访问公网IP的奥秘

3,281 阅读6分钟

目录

现在的家庭宽带,运营商基本上已经不会直接分配公网IP到户了,比如电信,都是通过NAT44来解决IPV4公网IP不够用的问题,从本地 ifconfig 得到的地址可以看到,自己的主机 IP 大多是10.x.x.x, 路由器直接获得的 IP 都是 10.X.X.X 类似这种的私网IP,然后路由器来进行NAT地址转换,NAT成从公网出去访问网络。

要详细了解NAT,这里我有必要先介绍两个头,生活在数据链路层的MAC头和生活在网络层的IP头,以及为啥他们要这样封装数据。

MAC头

mac头
mac头

1.以太网帧的内容很好理解,要找机器,需要目标MAC和源MAC;

2.类型两种一个是知道目标MAC正常封装数据帧发送;一个是不知道目标MAC需要先发送将包含目标IP地址的 ARP 请求,广播局域网所有主机找目标MAC地址然后再正常封装帧数据;

3.为了检测差错(比特差错0变1或者1变0)需要CRC循环冗余校验技术,底层是算法;

4.数据应该能理解吧,毕竟目的就是为了传输数据。

ARP角色如果不理解的可以看我的另外一篇文章

IP头

IP头
IP头

1.版本号目前是 IPV4,还有在推广的 IPV6 呢,先指明了;

2.区分服务类型代表了当前包的处理优先级,内核会按照队列里面的优先级顺序来处理包;

3.标识,标志和片偏移,因为数据报长度如果超过网络的 MTU 则必须分片,这些都是和分片规则有关的;

4.生存时间TTL,我们经常会用ping来查询网络情况,ping使用的是ICMP协议,设置差错报文TTL生存时间就是用来帮助侦查网络情况的;

5.协议是标明的 TCP,UDP 协议,下一层是传输层总要告诉人家用哪一种协议,要不然人家接收到了一脸萌萌;

6.然后就是 源IP 和 目标IP,目标IP是你要去的地方,对方接收数据返回结果的时候总要知道你在哪里,所以源IP稳稳的加上。

NAT(Network Address Translation,网络地址转换)

NAT来源

数据传输都是一去一回的,访问别人肯定要公网访问的,百度的域名和IP肯定都是交了钱租的公有的,可是我们这些老百姓如果每个设备都买个公网IP那我们岂不是要破产,买来了怎么配置还是个问题,我是个电脑小白咋办啊?物以稀为贵,以后如果 IPV6 普及了可能每个设备都能以白菜价租一个公网IP,但是IPV4的世界肯定不行。 所以就有了划分子网,我们平时在家里公司所处的都是一个个局域网,连接的WIFI的IP地址大部分都是 192.168.xx.xx 的私有IP,可是问题来了,每天那么多人同时访问百度,私有IP大家可以自己随意配制的重复常有,百度的返回结果怎么找到你呢?因此用脚趾头也能想到肯定是有个人帮我们做了转化。

NAT作用

NAT分为 SNAT 和 DNAT,分别对应将私有IP转换成公网IP,以及将公网 IP 转化为私网 IP,一发一收。我们的 Wi-Fi 里面的机器也是组成了一个局域网,所有的设备需要共享这个路由器的公网IP,当我们问百度 “辣条是卫龙好吃还是绯旺好吃啊?” 的时候,在我们路由器的出口,会做一次SNAT将私网IP转化为这个公网IP。

那么问题来了,百度回复你 “辣条都好吃” 的时候,DNAT 成哪一个私网IP呢?跑你妈电脑上去了可不就是一顿暴揍嘛,所以再发挥脚趾头的智慧就会猜测中间肯定有谁把访问记录了下来。

Iptables防火墙

iptables防火墙大家应该有耳闻,不知道 iptables 还没听过防火墙嘛是不,iptables 其实不是真正的防火墙,内核空间会有一个 netfilter,它是防火墙真正的安全框架。 Netfilter具有NAT,数据包修改,数据包过滤的功能。其中他会做连接跟踪,将如下映射:

<内部地址+内部端口>与<外部地址+外部端口>

放在到一张表里面,其实就是地址伪装,将内部IP和端口伪装成公网IP和端口,百度返回数据的时候查一下表就有了。 私有IP地址找机器,端口就是找到机器上面的应用程序,google 浏览器和火狐浏览器都是跑在机器上的一个应用程序,要找出是谁发问就看端口号了,计算机每个应用都会有自己的端口号,并且不会重复。

问题

知道了MAC头和IP头,以及NAT,别人发送一个网络包通过公网IP找到你所处的局域网网关之后,怎么找到你这台计算机呢,这里大家可以停顿先自行思考一下。

发送接收包
发送接收包

首先要知道,发送包的时候,是一层层加上各种头和数据的,接收到包是一层层解开包,一步步拆开拿下包的各种头最终到了相应的应用就变成了数据的。

自己的主机肯定是有一个IP的,假设主机在局域网里有一个私网IP,发送包的时候,比如你的Java代码的跑在Linux平台要访问百度,Linux平台会调用内核判断 if 百度的IP和自己的在一个网段那么就是局域网之间的访问,直接通过那个相同网段的网关发出去,否则 else 不在同一个网段,直接从公网网关出去访问百度。

那么接下来的思路是:

  1. 先看是不是我这台机器拥有的的网关能识别的MAC,拿下它的MAC头看看,如果对不上不是我的那么只是路过,拜拜
  2. 如果是我的MAC,收进来,再拿下他的IP头,判断他的IP,网关再根据他的IP网段判断是从哪个关口出去,从而找到了机器所在局域网网口
  3. 这里再根据IP地址,详细的找到这个IP地址是对应哪一台机器,网关这个地方都是有ARP缓存的,缓存里面有机器私网IP和机器MAC地址的对应关系,缓存里面如果有那么找到了这台机器了,缓存没有的话直接发起一个ARP协议广播问一下这个IP的MAC地址是谁
  4. 找到这台计算机之后,从计算机网卡进去,再根据端口来判断是找哪个应用的,该是去QQ的找QQ,找微信的找微信。
  5. 上面处理完之后,微信或者QQ返回一个结果,将这结果发出去,别的机器重复这个判断过程

如果有收获,路过的朋友点个“在看”吧,鲁迅说“四连是美德”,关注我更好啦。