需求分析
微信公众号的开发过程中,微信服务器和项目的后端会相互发送信息。如果需要测试,就必须保证项目可以被公网访问,但大多数情况下家庭网络都是经过了运营商层层 NAT 之后的网络,并没有公网IP,此时就需要使用内网穿透来解决“公网访问”的问题。
实现内网穿透后,就可以在微信的公众号页面设置 URL 到自己的项目上了。
“为什么我的电脑不能被公网访问到?”
早期的互联网的总设备量还没有那么多,运营商确实会给每个用户都分配一个公网 IP,大家都在公网上其乐融融。
但随着设备增加,IPV4的地址池即将耗尽,运营商不得不减少 IP 地址的使用来让互联网容纳更多的设备,NAT 技术实现了节省 IP 地址的目的。
NAT
NAT 全称“网络地址转换”,它允许局域网内的一系列设备使用同一个公网地址发送数据,而路由器会记录下转换的过程,并在收到公网的返回之后根据之前的记录转发给内网。
具体的转换过程是:内网地址+端口 <--> 外网地址+端口,如图:
① 当位于局域网192.168.1.100的电脑1想访问公网服务器39.100.100.100的 Web 端口8080时,由于它不知道服务器的具体位置,所以向它的网关(路由器)所在的192.168.1.1发送请求(Request)(这个请求会随机从一个空闲的高位端口发出,如27777)。
② 路由器一侧连接公网(WAN),一侧连接内网(LAN),当路由器收到请求(Request)后,由于路由器知道服务器的位置,所以会把数据转发出去,但内网数据包不允许在公网上转发,于是数据会被转化成源地址是公网的地址的数据包,也就是把请求头变成路由器的公网地址122.122.122.122,并且随机使用一个空闲的高位端口,如60000。
③与此同时,路由器会记录下内网到外网的转换关系,也就是 192.168.1.100:27777<---->122.122.122.122:60000,如果后面服务器向60000端口返回数据,路由器就知道这个数据应该返回给电脑1所在的192.168.1.100。在电脑1和服务器的连接断开之前,这条映射规则不会失效。
④ 服务器收到数据包后,它只知道发送人是位于122.122.122.122的路由器,并不知道真正的发送者,所以返回(Response )数据也会发送到路由器的公网地址122.122.122.122
⑤路由器收到服务器的 Response 后,通过查看NAT 表知道,这个数据应该返回给电脑1,所以把 Response 发送到192.168.1.100
这样就完成了一次请求和返回,当连接断开一段时间后,NAT 表的记录失效。
但 NAT 的原理就决定了它有一个问题:公网无法主动向内网发起请求,这就导致了家里的电脑无法做服务器。
如图:
① 如果公网电脑主动向路由器发起请求(Request)
② 路由器查询 NAT 表之后发现并没有记录,因此不知道转发给哪一台内网机器,数据被丢弃。
看到这里读者可能会想,既然能通过 NAT 表完成临时的端口对端口的映射,并且来自公网的 Response 可以转发回来,那么有没有一种方法,能实现一种“长久的”端口映射,这样公网服务器是不是可以通过特定的端口来主动连接内网服务器呢?
确实是可以的,而这种方式叫做端口转发,用一个固定的“端口转发表”来记录永久的转发规则
端口转发
如图:
①在路由器中设置好规则:将公网的60000端口映射到内网电脑1的8080端口
②服务器向路由器发起请求时,发送到122.122.122.122的60000端口
③路由器通过端口转发表,知道了该把数据发送到192.168.1.100的8080端口
④路由器把数据发给电脑1
经过这么一通操作,我们可以理解成,端口转发把电脑1的8080端口变成了“公网上的端口”
DMZ
还有一种特殊的端口转发叫做 DMZ,它可以理解为“所有端口都转发”,也就是只要有来自公网的请求,全部都转发给电脑1
那么为什么我用了端口转发还是不能被公网访问到呢?
上文的例子是一个理想情况,它的前提在于:路由器是自己家里安装的,并且运营商给路由器分配的地址是公网地址,换言之,只经过了路由器这一层 NAT
但实际的情况是,在家庭宽带连接到路由器之前,运营商就已经进行了好几层 NAT 了,也就是说,或许一个小区通过 NAT 共用了一个 IP 地址,再换句话说,到达我家的网络,已经是一个内网地址了。如图:
所以这种情况再使用端口转发就没有意义了,我们可以突破家里路由器的 NAT,但无法突破运营商的 NAT。
除非我们能控制运营商的路由器,在他们的路由器上,一层一层的设置转发规则,直到最外层的路由器,但这并不可能。
所以就有了内网穿透的方法
内网穿透的原理
内网穿透需要借助一台在公网上的电脑(这台电脑的作用就是转发数据,我们称为跳板机),本质上是使用内网电脑连接到跳板机,建立长连接(长连接的作用是保证 NAT 表一直有效),并完成端口的一一映射,当其他设备需要访问内网电脑时,只需要访问到我们的跳板机,由跳板机转发到内网机器,如图:
①内网电脑启动内网穿透,主动连接到位于公网180.2.2.2的跳板机
②连接过程中,途径的各级路由器都会产生 NAT规则,并且由于即将形成长连接,这个 NAT 规则不会失效
③内网电脑和跳板机握手后形成了长连接,也就是一直抓住不断开,此时双方都可以随意向对方发送数据,
此时我们可以设置一份规则,只要有人向跳板机的8080发送数据,跳板机就向内网机器的8000端口发送数据
④如果有其他电脑想访问内网机器,只需要连接180.2.2.2的8080端口
⑤跳板机沿着隧道把请求转发到内网上
⑥内网机器处理完之后,会把返回的数据发送到跳板机上
⑦跳板机会把数据返回给发起请求的电脑
这样就实现了从公网主动向内网发起请求。
总结
什么是内网穿透:在公网上部署一个负责转发的跳板机,与内网主机进行长连接,当其他设备访问跳板机时,跳板机将数据转发到内网主机,实现内网穿透
为什么使用内网穿透:① IP 地址池有限 ② NAT 技术使得外网无法主动向内网发起请求 ③端口转发不适用于多层 NAT 的情况
多看看上文的几张图片,可以有更好的理解。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。