Nat内网穿透详解与实战原理

作者:小成Charles
商业工作,学习交流请添加Vx:Lcc-Triumph
原创作品
转载请标注原创文章地址:https://blog.csdn.net/weixin_42999453/article/details/130303370

一、引言

在解释内网穿透这件事之前,我先抛出一个问题:如果让你来设计一套框架去实现两台内网主机进行通信,你会怎么做?
一个非常直观的设计就是先准备一台拥有公网ip的服务器命名为Server,然后两台处于同内网下的客户端主机,分别为ClientAClientB,然后两台客户端机器分别连接服务器。这时候服务器充当一个数据中转站,把ClientA发送的数据转发给ClientB,反正同理,这就实现了两台内网的客户端之间的数据通信。(如图所示)
在这里插入图片描述

但是细心的同学会发现,这样做导致服务器的压力太大了,数据信息全都要经过服务器进行转发。那有没有一种方式去实现两台内网主机直接通信进行数据传输呢?当然有,那这就涉及到内网穿透的知识了。

二、什么是Nat?

想知道内网穿透实现原理,先弄清楚我们平时在网络冲浪的时候,数据是如何发到服务器的又是如何接受到数据的?我相信大家都知道,我们客户端在发送数据给服务器的时候,首先服务器的ip地址和端口我们是事先知道的,服务器接收到客户端的数据请求的同时也获取到了客户端的公网ip地址和端口,然后服务器根据客户端的公网ip地址和端口返回数据。
那就很清晰了,数据接收和发送都是通过公网ip和端口进行传输的,那我们直接获取到两台主机的公网ip地址和端口就可以实现跳过服务器中转站直接进行数据通信,其实这就是实现内网穿透的原理。但现实情况没那么简单。
因为IPV4的地址太少了,我们不可能每个人都有一个公网ip地址,所以运营商会在一个固定区域内设置Nat服务器,这个Nat服务器拥有一个公网IP地址。当我们网上冲浪的时候,客户端会先将数据信息发送给Nat服务器,这个Nat服务器会为你这个内网IP的客户端分配一个固定的公网ip地址+端口,然后再把数据发给服务器,服务器接收到数据之后会先根据这个公网IP地址和端口返回相应的数据,但是此时数据只是发到了Nat服务器,内网客户端并没有接收到,此时Nat会根据端口号映射到指定的内网主机,实现数据的传输。具体流程如下图
在这里插入图片描述

例子:ClientA的内网IP为192.168.1.2:4567,ClientB的内网IP为192.168.1.3:2389.经过Nat被映射为公网Ip地址,ClientA被映射为10.2.6.4.1:6666,ClientB被映射为10.3.5.7.8:9999。当服务器发送数据给10.2.6.4.1:6666,就会被转发到192.168.1.2:4567,也就是ClientA。如果有多个Client在同一Nat服务器发送数据时,Nat就会就会通过给每个内网ip映射一个IP地址:端口号,其中IP地址是不会变的,改变的是端口号。
总结:所以Nat其实就是一个用来给内网IP地址分配公网地址的服务器

三、内网穿透实现原理

搞清楚了Nat服务器,那实现起来就很简单了。如图所示。ClientA发送数据的Ip为192.168.1.2:4567,经过Nat映射为公网IP10.2.6.4.1:6666,然后将当前的公网IP发送给Server实现注册保存,同样的ClinetB把公网Ip10.3.5.7.8:9999发送到服务器注册保存。接着服务器把双方的的公网IP地址发送给对方,这时候双方都有对方的IP地址了,就可以直接对两个客户端直接建立连接实现数据的传输了。而这个过程中,服务器的数据流只有IP信息,实际数据通过两台客户端建立连接直接传输,这也是P2P网络的经典实现方法。
在这里插入图片描述

但是Nat又分为很多种,主流的分为锥型和对称型Nat,对于不同的Nat在做内网穿透的规则有不一样。

1)Full Cone NAT(完全圆锥型)

这种会将同一私网地址端口192.168.1.2:4567发至公网的所有请求都映射成同一个公网地址端口10.2.6.4.1:6666,192.168.1.2可以收到任意外部主机发到10.2.6.4.1:6666的数据报,这种类型的客户端局限性最低。
也就是说,只要知道私网地址被映射成的公网ip,任何公网IP对其发送数据,这个私网下的所有端口都能接收到此数据。

2)Address Restricted Cone NAT (地址限制圆锥型)

这会将从同一私网地址端口192.168.1.2:4567发至公网的所有请求都映射成同一个公网地址端口10.2.6.4.1:6666,只有当内部主机192.168.1.2先给服务器Server 6.7.8.9发送一个数据报后,192.168.1.2才能收到服务器Server 6.7.8.9发送到公网地址端口10.2.6.4.1:6666的数据报。
注意理清楚这里面的细节,地址限制圆锥型的意思就是说,私网地址接收到数据的这个公网IP必须是这个私网地址曾经发送过数据的IP地址(这就是一种映射规则),当前私网地址下的所有端口都能接收到此数据。

3)Port Restricted Cone NAT(端口限制圆锥型)

与受限制锥型基本一样,区别就是最后私网地址下只有指定的端口号才能接收到数据。
这会将从同一私网地址端口192.168.1.2:4567发至公网的所有请求都映射成同一个公网地址端口10.2.6.4.1:6666,只有当内部主机192.168.1.2:4567先给服务器Server 6.7.8.9发送一个数据报后,192.168.1.2:4567才能收到服务器Server 6.7.8.9发送到公网地址端口10.2.6.4.1:6666的数据报。

4)对称NAT(Symmetric)

对不同的外网IP地址都会分配不同的端口号。把所有来自相同内部主机IP地址和端口号,到特定目的IP地址和端口号的请求映射到相同的外部IP地址和端口。如果同一主机使用不同的源地址和端口对,发送的目的地址不同,则使用不同的映射。只有收到了一个IP包的外部主机才能够向该内部主机发送回一个UDP包。对称的NAT不保证所有会话中的(私有地址,私有端口)和(公开IP,公开端口)之间绑定的一致性。相反,它为每个新的会话分配一个新的端口号。
如果是对成型的Nat不适合做内网穿透,最后总结我会说。

这几种类型的Nat逐渐局限型越来越高,接下来我会根据端口限制圆锥型Nat设计一个穿透过程:

UDP穿透流程

  1. ClientA 和 ClientB分别通过Nat与服务器进行通信,服务器只存储两个客户端的公网IP地址信息。
  2. 服务器接收到数据时分别将对方的IP地址信息发送给双方
  3. 此时,ClientA 拥有了 ClientB的公网地址,ClientA先发送一个探测数据给ClientB的公网IP,但是ClientB接收不到数据,因为根据协议,NatB中的映射没有这条规则,也就是说NatB并没有发送过数据给NatA,那就接收不到来自NatA的数据,但此时NatA添加了一条NatB信息的映射规则。
  4. NatB发送一条探测数据给NatA, NatA收到了。因为NatA在上一步骤中发送数据给NatB了,有了这条映射规则。
  5. NatA 在发送一条探测数据给NatB,NatB此时也收到了。
  6. 现在,UDP隧道建立成功,可以进行数据传输了。这个过程也叫做UDP打洞。

对称NAT(Symmetric)的内网穿透

根据这个流程我们会发现对称NAT(Symmetric)不适合做内网穿透,举个例子,如果两个客户端都是对称NAT根据上述流程就没法穿透了。

  1. ClientA 和 ClientB分别通过Nat与服务器进行通信,服务器只存储两个客户端的公网IP地址信息。
  2. 服务器接收到数据时分别将对方的IP地址信息发送给双方
  3. 此时,ClientA 拥有了 ClientB的公网地址,ClientA先发送一个探测数据给ClientB的公网IP,但是此时对于ClientB发送数据的IP已经和服务器所保存的IP不一样了,因为对称NAT对于不同的公网IP地址发送数据所对应的端口是不一样的。那后面流程就没法继续了。

那两个对成型如何穿透呢,除非你能够准确的猜出客户端每次映射的端口号是多少(这个理论上可以实现,但是稳定性很低)

是否可穿透组合

下面是是否可穿透的Nat组合
在这里插入图片描述

Nat类型检测工具

工具下载地址:https://github.com/HMBSbige/NatTypeTester
打开软件导航选择RFC 3489,点击Test 。

四、总结

实际上操作内网穿透可能会更加的复杂,两台主机在同一个Nat下可能会无法穿透,因为有的Nat不允许数据回流,还有可能出现多层Nat穿透的情况,关于这一部分已经代码实现,我将会在下一期更新。

作者:小成Charles
商业工作,学习交流请添加Vx:Lcc-Triumph
原创作品
转载请标注原创文章地址:https://blog.csdn.net/weixin_42999453/article/details/130303370

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值