内网穿透与VPN

内网穿透与VPN

Scroll Down

什么是内网穿透

内网穿透,即 NAT 穿透,简单来说就是让外网能够访问本地的服务。
外网 IP 比较昂贵,企业虽然有少量独立的外网 IP,但是出于成本限制无法为每一台主机提供一个外网 IP,或者出于安全限制并不是所有的服务都需要暴露到外网中。所以企业就有可能使用 NAT 技术将大量内网 IP 通过一定规则映射到少量的外网 IP 上。
通过 NAT 技术,我们可以访问到外部网络资源,但是弊端是外网并不能向内网主机发起请求,这时候就要借助于内网穿透服务。

什么是 NAT 技术

NAT 网络地址转换

上面提到了 NAT 技术,什么是 NAT 技术?NAT(Network Address Translation,网络地址转换)简单来说就是将大量内网 IP 通过一定规则转换为少量外网 IP,实现内网用户能够访问外部资源的技术。一般是在路由器上搭建 NAT 网关,网关上维护内网 IP 与外网 IP 的映射表。NAT 技术的实现方案有许多中,下面介绍比较常用的一种。

NAPT 网络地址端口转换

NAPT(Network Address Port Translation,网络地址端口转换)是 NAT 技术的一种,因为一个 IP 可以对应多个 端口,所以通过多个内网 IP 跟单个外网 IP 的多个端口映射关系实现信息通讯。
NAPT 实现原理是这样的,举个例子,假如内网有两台机器分别是:192.168.1.1、192.168.1.2,路由器上的外网 IP是:162.105.178.62 。当 192.168.1.1 这台机器访问外网的时候,路由器上的 NAT 网关会自动分配一个端口 6666,同时保存端口跟内网 IP 的映射关系(6666 -> 192.168.1.1)。路由就会以 162.105.178.62:6666 的方式访问外部资源,当外部资源有所响应的时候数据也会发送到 162.105.178.62:6666 这个地址,这时候就会根据端口查 NAT 网关映射表,发现 6666 端口跟 192.168.1.1 的映射关系,把资源返回到 192.168.1.1 这台机器上,如下图所示:
napt.jpg
举个更通俗的例子,出去购物,商家至少要知道所在的小区和门牌号才能为我送货,货物送到小区物业那,小区物业根据门牌号送到我家,这时候我所在的小区就是外网 IP,门牌号就是端口,物业就是 NAT 网关,我家就是内网机器。

NAT 的局限

但是 NAT 技术也有局限,外网无法主动向内网机器发起请求,不过也是出于安全性的考虑。上面的过程中只有内网先发起请求,NAT 网关才会建立映射关系,没有了映射关系内外网的通道就无法打通了。
就好比是门牌号是变化的,物业在出门前才发放门牌号,外来人没有门牌号无法找到我家。

跟 VPN 的区别

VPN(Virtual Private Network,虚拟专用网络),通常用来做两件事情,一个是可以让世界上任意2台机器进入一个虚拟的局域网中,一个是可以用来翻墙。
实现原理是通过操作系统虚拟一张网卡,虚拟网卡会跟 VPN Server 协商得到一个虚拟的局域网 IP ,数据经过网卡进行拦截,通过加密封装后转发给 VPN Server,如果是虚拟局域网用户之间的通讯就把请求根据虚拟局域网的 IP 进行转发就可以了,如果是为了翻墙的话,假如访问谷歌,VPN Server 会去修改数据的源 IP 为 VPN Server 的 IP 地址,然后将数据发给谷歌实现数据互相通讯,这点跟 NAT 很类似,如下图所示:
vpn.jpg
这么说 VPN 也可以实现内网穿透的功能,但是跟接下来要讲的内网穿透实现有区别:

  • 用户的使用的成本有点大,用户为了访问内网的服务需要安装 VPN 客户端来虚拟网卡,这点不如为内网机器提供一个外网 IP 方便
  • 使用场景不太一致,VPN 能够提供内网机器的所有端口服务,然而接下来要实现的内网穿透主要是为单台机器单个端口提供服务,所以 VPN 一般用于虚拟办公环境而不是用于提供单一的服务

为什么不用Nginx实现

首先Nginx能做什么?负载均衡和动静分离就不多说了,偏题了,说说 Nginx 作为代理的功能:

  • 正向代理
    正向代理是将请求转发到对应的服务器上,但Nginx 部署的代理服务器和目标服务器都不在一个网络环境,都有各自的外网 IP。这跟我们要实现的是为目标服务器提供一个外网 IP的需求不符。
  • 反向代理
    反向代理,也就是将外部的请求转发到内部的服务器。反向代理可以实现内网穿透的功能,但前提是内部服务器跟 Nginx 部署的代理服务器在同一个网络环境,如下图所示:

nginx.jpg

其他场景

上面说了通过反向代理,也可以实现内网穿透的功能,但更多的情况是代理服务器跟内部服务器部署在不同的环境,这种情况下 Nginx 就无法满足了。所以接下来讨论并实现的是这种 Nginx 无法满足的情况。

实现原理

要实现内网穿透,前提是要有一个能够访问外部资源的服务器作为代理,如果这台服务器也同时处在内网环境中,那通过 Nginx 的反向代理就能够实现。但现实是服务器所处的网络都相互独立,代理服务器跟内部服务器之间的桥梁没有打通。但是可以通过建立 Socket 通讯隧道方式建立代理服务器和内部服务器之间通讯,再由代理服务器访问外部资源传达给内部服务器。
内网穿透工具一般分为 Server 端还有 Client 端。Server 端部署在代理服务器上,主要负责管理 Client 端的通讯,将请求分发到对应的 Client 端;Client 端部署在本地机器上,一般是随启随用的,主要负责把 Server 端的请求分发到对应的本地服务上,下图简单描述了下通域名映射的方式实现的内网穿透流程:
nat.jpg

这种实现方式是不是跟 NAT 的实现原理异曲同工。那么我们延续 NAT 的流程也举个通俗的例子来解释下,小区的服务升级了,外包了一个服务站点,外人想要访问你家需要你去服务站点提前填写申请表格,当外人到小区的时候查询下服务站点的表格就知道你家的位置了,这里的服务站点就是内网穿透工具,申请表格就是 Server 端和 Client 端的映射关系。
下面通过域名的映射方式说下实现过程:

准备阶段

假如本地的 8000 端口服务需要内网穿透服务,首先要起 Client 端来建立本地 8000 端口服务跟 Server 端的通讯连接,Client 端会发起一个请求给 Server 端,Server 端收到请求会去创建一个跟 Client 端的通讯通道(一般是 Socket 连接)并分配一个子域名假如是 a.example.com,Server 端会保存子域名映射关系(a.example.com -> Client 端 Socket 连接),最后将子域名返回给 Client 端。准备阶段完毕,访问 a.example.com 就相当于访问本地 8000 端口服务。

请求阶段

当访问 a.example.com 的时候,请求首先会到 Server 端,通过查询子域名映射关系找到对应的 Socket 连接,通过 Socket 将请求返回给本地 8000 端口服务,待处理完毕再原路返回。

销毁阶段

当关闭 Client 端的时候,Server 端通讯通道(Socket连接)会被关闭,这时候需要销毁相应的域名映射关系。

参考阅读:

转载自: 使用Node实现简单的内网穿透