负载均衡篇-LVS引出的网络知识:NAT、内网穿透及P2P

NAT 技术

NAT:网络地址转换。不知道大家有没有好奇过这个问题,即:

公司里面的电脑不能被外部网络直接访问,因为我们都属于内网,公司里各电脑同享一个公网IP。

但是,我们却能够主动连接外网,比如能够登录微信,和别人聊天,同时也能收到回复

这是为什么呢?

这就是路由器里面的NAT转换功能的作用。假设路由器的公网IP地址为 120.240.1.121,路由器所接两台电脑的IP地址为:A:192.168.1.2 和B:192.168.1.3。

假如现在登录了微信,如果微信服务器的端口为8080,则A电脑和微信服务器建立连接后,路由器内的NAT转发规则表就如下:

外部网络 内部网络
120.240.1.121:8111 192.168.1.2:8080

路由器发给微信端的数据包中,源IP和源端口号就变成了:120.240.1.121:8111,其中,8111是路由器自动分配的,路由器暂时记录下这个规则。

那么当微信服务器返回数据时,目的IP和目的端口号就变成了:120.240.1.121:8111,所以是由路由器来接收到该数据包,当路由器根据NAT规则查看时,就知道了要将该数据包的目的IP和端口转换成: 192.168.1.2:8080 这样子。

也就是直接修改协议的报文内容,修改完成后再校验一遍校验和即可。

这样子对于A电脑来说,他收到的报文中,A电脑会认为该报文就是微信服务器直接发回到自己的。

上述一系列过程引出了三个问题,即:

  1. NAT规则表建立的时机
  2. NAT规则表缓存时长
  3. 外网为什么不能主动连接内网主机

首先是NAT规则表建立的时机。网络数据包通过路由器进行交互的时候就会进行规则表的建立。这里存在的一个子问题是:

由于NAT这种模式(PAT)需要端口号,那么传输层即TCP、UDP之上的肯定没问题。但是比如ICMP这种协议呢?它协议中没有端口号这种东西,那么当我们进行 ping 指令的时候,ICMP包是如何通过路由器访问到外网机器并且又是如何传送回来的呢?这一点我们再后续研究。

作为这里的补充,有必要说明一下NAT的几种转换方法:

  1. 静态NAT:一个公网IP转换成一个内网IP地址
  2. 动态NAT:多个公网IP动态的转换成多个内网IP地址。只不过要动态的维护这个转换集合,当内网设备断开连接后,要释放IP映射资源
  3. 地址及端口映射 NAPT:就是上文说的带有端口映射的规则。这样子只需要一个公网IP就可以映射多个内网IP。由于这个用的最多,我们就忽略上述两项了。

NAT映射表的缓存时长是多少呢?一般可能在某个内网IP几分钟或者十几分钟内不再收发包了,就删除。或者在连接主动断开后也会删除(猜测)。

规则表缓存时长就引出了一个子问题,也就是心跳问题,比如A电脑和微信服务器建立了连接以后,如果长时间不发送消息也不发送心跳的话,那么当NAT规则表缓存清除后,微信服务器假如要主动下发命令给A电脑,那么A电脑是肯定接受不到了。因为路由器不知道把这个命令发给内网的哪台电脑。

最后,为什么外网不能主动连接内网的主机呢?因为主动连接时,并不知道内网的IP是什么,知道了也没办法直接连接到内网。那么,假如内网中的A主机首先和外网建立过连接,那么路由器端肯定生成了NAT规则表。假如,此时我能够知道NAT转换表的内容,也就是知道了在路由器侧对应的内网A主机的端口:

那么,是不是我就能够直接在外网通过路由器公网IP加这个NAT端口来主动和A主机建立连接呢?

这里暂时无法辨析,估计有如下两点:

  1. NAT设备禁止外部网络主动和内网网络建立连接,这样子肯定要安全点。
  2. 可能我们无法获取到NAT转换表。不过可以通过抓通过路由器的包来确定,此处暂时不做进一步研究。

那么,我们该如何通过外网主动与内部网络建立连接呢?

这就是内网穿透技术。

内网穿透

大名鼎鼎的花生壳一些人都用过,有了它,我们就可以通过一个域名(花生壳提供)和指定端口来访问我们内网中的主机了。使用花生壳,需要在内网主机上安装 花生壳 软件,然后配置一下映射规则后就可以外网访问了。配置如下图:

规则配置

那么,这一背后的原理是什么呢?

在不引入其他知识的情况下,我们可以先盲猜一波:

花生壳软件主动和花生壳服务器建立连接,然后二者就可以相互通信了,这一点是肯定可以的,因为路由器会建立NAT映射表。此时,花生壳服务器记录下这个客户端的IP和端口(实际上就是路由器的IP以及NAT表记录的该条映射的端口)。

当外部网络访问花生壳提供的域名后,DNS当然会解析到花生壳服务器上,花生壳服务器在缓存的列表中找到这个域名和端口对应的是哪台花生壳客户端电脑,然后再把该请求的目的IP和端口,修改成客户端所在路由器的IP和映射端口。

这样子,该条请求就会发到路由器,路由器通过NAT表会将该条请求转发到花生壳客户端,客户端再通过映射规则,将其转发到本地的某个程序。

实际上,大致过程也是这样子的。

P2P网络及打洞

另外一种相关的技术叫做P2P,即对等网络技术或者是点对点通信。为什么会叫对等网络呢?因为在该网络中,会认为网络是去中心化,所有的节点既是客户端又是服务器。

这里回忆一下以前下载东西的时候,会看到下载软件会有类似提示:该资源有多少人正在下载,会为你加速xxx。当时不太明白这其中的原理,现在回过头分析一下,继续结合上述的知识盲猜一波:

下载软件和其远程服务器将各个用户的电脑组成了一个P2P网络,又由于NAT转换表的存在,使得各个用户的电脑在逻辑上连接在一起。当你下载一个BT资源时,会从各个拥有该资源的用户处下载组成该资源的一个个分块,最终在下载软件收集到所有资源块时,再将其组合成一个完整的文件,就下载完成了。这也是为什么总是下载到99.99的时候特别慢的原因。

上述是非常粗略的一个分析。具体来说,还有如下两点没解决:

  • 不同用户之间的电脑如何相互进行访问
  • BT下载的过程

打洞

想要了解不同电脑的之间如何相互访问,首先要理解 打洞 这个概念。从上文的NAT转换规则我们可以看到,NAT的映射规则,实际上就是在路由器上打了一个洞,这个洞外面是外部网络,里面的另外一端是内部网络中的某台电脑。

打洞具体可以根据UDP和TCP的划分分为两种,但是宏观层面上区别不大,这里就简要说明一下有意思的打洞。

A
服务器
B

首先,A、B两台电脑需要主动和服务器通信,比如UDP或者TCP等。这样子通信过以后,结合上文所述,实际上服务器就可以缓存下A和B的公网IP以及对应的端口号(NAT外网规则的),并且,A和B的路由器端也会记录下相同的NAT转换规则。然后假如服务器告知B电脑,IP1和端口233是A电脑的地址,那么B就可以主动去和A通信,并且是可以通信成功的。

成功的原因在于:B发送命令的IP和端口号就是A所在路由器的IP以及映射的端口号,由于A端路由器NAT规则仍然存在(所以需要心跳),使得路由器会将B发送的帧成功转发给内网的A电脑,这样子A和B就可以成功通信了。

实际上,由于有些路由器确实会禁止外部网络主动发起的SYN连接请求,所以TCP协议的打洞要复杂一些。由于UDP并不是面向连接的协议,不需要事先建立连接,所以UDP协议打洞是比较简单的。

但是不论怎样,都要涉及到两台及以上电脑和服务器之间的交互,打洞的核心点在于:

  1. 欺骗路由器,使其生成NAT规则,也即使其在自己身上打了一个洞,洞内就是目标服务器,洞外就是外网环境
  2. 服务器端记录各电脑的IP及端口等等。
  3. 经过一系列的通信及交互,最终在不同的路由器上成功打洞,并且各电脑之间知道能够去连接的各个IP以及端口号。

BT 下载过程

有了上面的铺垫,BT下载的基本原理就会清晰一些。P2P软件将各个电脑组成一个P2P网络,组成的方法及原理和打洞相同。当该网络中,一台电脑A要下载某个文件时,BT种子文件中已经记录该实际文件的信息,比如:该文件总大小4G,该文件被切分成了10M一个块,总共有400个分块等等。

A电脑上的下载软件首先去中央服务器问询,告诉他下载哪个软件等等,然后中央服务器返回这个网络中一批当前可用的P2P节点(比如正在下载该资源的电脑或者正在登录的电脑)。A拿到这个可用的节点信息后,就会与这些节点通信,也即从各个节点中分块下载不同的资源块,等下载完成后,再将各个资源块整合起来,形成最终的下载文件。

诉他下载哪个软件等等,然后中央服务器返回这个网络中一批当前可用的P2P节点(比如正在下载该资源的电脑或者正在登录的电脑)。A拿到这个可用的节点信息后,就会与这些节点通信,也即从各个节点中分块下载不同的资源块,等下载完成后,再将各个资源块整合起来,形成最终的下载文件。

这是个简要的过程,实际上P2P网络以及BT下载还涉及到很多有意思的东西,先简要理解,后续可以继续。

发布了39 篇原创文章 · 获赞 74 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/zhou307/article/details/100064314