我们在家时,电脑或者手机实际上是连在一个局域网中,我们称其为内网。他们可以通过路由器可以连互联网。内网的电脑或者手机也可以互联。但是,却无法透过互联网主动连接到内网的电脑或者手机。这是因为路由器使用了NAT(网络地址转换)。这个技术导致我们的电脑和手机可以访问互联网,但是,互联网上的电脑却无法主动访问我们。如果想要通过互联网访问我们家里的电脑和手机,就需要使用内网穿透技术。换句话说,内网穿透就是将内网的电脑暴露在互联网上,让其他人可以透过互联网主动访问到这台电脑。

典型的如一些遥控软件,向日葵、TeamViewer等等,就是基于内网穿透技术做的远程遥控软件。如果你了解VNC,你就会知道它是一款局域网内的遥控软件。如果给它加上内网穿透技术,那就成了向日葵或者TeamViewer类似的遥控软件。

我们在局域网中经常会使用网络共享,把A电脑的文件共享给B电脑。如果给它加上一个内网穿透,就变成了一个简单的私人网盘服务器。

当然,内网穿透的应用还要很多。总之,如果你想在家里电脑中玩出花样来,内网穿透是基础的基础。

1. 背景知识

1.1 NAT(网络地址转换)

举个简单的例子,我们上网买东西时,都会在购物网站上留下地址。但是,为了隐私,我们不会留具体的地址。比如,我家准确的住址是:南京市A区B小区C幢D室。但是,我买东西时只会留:南京市A区B小区,同时留下一个电话13012345678。东西寄过来的时候快递员就会打电话给我,问我具体住哪儿,再把东西送过来。或者把东西送到菜鸟驿站,菜鸟驿站会发短信给我,让我去取快递。如果,我留的这个电话号码是一次性的,每次买东西都会发生变化,那么就跟NAT完全相同了。这样一来,我们买东西时,买的东西可以成功寄到家。但是,购物网站却无法主动寄东西给我们。即使我们曾经从这个购物网站买过东西,它也无法联系到我们。因为电话是一次性的,地址是模糊的。这样,也就保护了我们,免受到了一些可能的非法侵害。
在这个模型中,菜鸟驿站或者快递员就是我们家安装的路由器,包裹就是数据包,你家是内网电脑,购物网站的商家就是互联网上的电脑。

通常,我们家中电脑的网络拓扑结构为:

flowchart LR subgraph 内网A a(电脑A) b(电脑B) r(路由器) end i1(服务器1) i2(服务器2) i3(服务器3) a--端口号1234-->r b--端口号3456-->r r-.->i1 r-.->i2 r-.->i3

在访问互联网时,局域网中的电脑A和电脑B,不会把电脑的具体地址(具体到门牌号)告诉给服务器,而是使用了路由器的公网地址(小区地址)。同时,访问互联网时会找路由器申请一个端口号——一次性的电话号码。然后,互联网上的服务器回复的信息也会发送到路由器上面。路由器再根据端口号,将信息转发给具体的电脑。于是,我们的电脑可以主动访问互联网。其交互时序为:

sequenceDiagram participant a as 电脑A(内网地址:192.168.0.2) participant r as 路由器(内网地址:192.168.0.1,公网地址:1.2.3.4) participant i as 网站服务器(公网地址:2.3.4.5) a-->>r: 往网站服务器发送数据 r->>r: 将数据包中的源IP地址换成自己的公网IP地址1.2.3.4 r->>r: 将数据包中的端口号地址换成本机的某个空闲端口号1234 r->>r: 记下本地端口1234、192.168.0.2以及网站服务器地址的关联关系 r-->>i: 发送修改好的数据包 i->>i: 解析并接收到的数据包 i-->>r: 回复一个数据包给1.2.3.4:1234 r->>r: 根据公网IP和目标端口号判断数该数据包真是的目标机器 r-->>r: 修改数据包中的目标地址信息 r-->>a: 转发回复的数据包

很明显,网站服务器却无法通过互联网主动访问我们内网的电脑A。这是因为数据包只能发送到路由器。因为没有关联关系,所以,路由器并不知道要将这个消息转发给谁。通常路由器只会把这类数据包简单的丢弃掉。

如果你使用的路由器比较高级,你可以告诉路由器,这种数据包不要丢,全都转发给电脑A。于是,电脑A也就相当于暴露在了互联网上面。当我们给路由器的公网IP发送数据的时候,这个数据就会被转发到电脑A。比如,Padavan系统的路由器中,就可以看到下面的配置项:

image-20230108173359359

在这个界面中,我们配置一个内网主机IP就可以实现将内网电脑暴露在互联网中。

接下来,我们就可以在电脑A部署各种系统了,比如各种网站或者后台服务,为互联网用户提供服务。

1.2 DDNS(动态域名解析)

通常我们访问某个网站,不会直接访问该网站的公网IP,而是访问它的域名。先通过DNS(域名解析)技术,将域名翻译成IP地址,再往这个IP发送数据包。这是因为IP地址很难记忆,而且IP地址容易发生变动。比如我们的路由器,每次拨号后,公网IP都会发生变动。这就给我们通过互联网连接我们内网的服务器带来了麻烦。于是,DDNS(动态域名解析)技术应运而生。DDNS的做法是,每当路由器的公网IP地址发生变化的时候,就告诉DNS服务器,将域名解析到新的IP地址。

比如Padavan系统的路由器中,我们就可以通过Aliddns插件使用阿里云的动态域名解析。当然,华为和腾讯等也都会对应的插件,可以实现DDNS。

通过上面的一顿操作以后,我们就可以如果访问百度一样的访问,我们在内网电脑上搭建的各种服务了。

2. 公网IP

然而,现实情况却没有那么简单。宽带服务商,并不想让我们在家搭建服务器。一方面,家用的带宽比较便宜,而企业带宽比较昂贵,如果我们都使用家用带宽搭建网络服务,就会大大影响他们的利润。另一方面,还会给他们带来很多带宽压力。比如开通的是百兆宽带,但是,实际使用的宽带很少能跑满,大多数时候都是空闲的。如果,我们搭建了服务器,那么带宽的使用率也会上升,从而给服务商带来压力。所以,服务商会给我们设置诸多障碍。

2.1 电信

使用电信的宽带时,会给我们一个光猫。这个光猫会带有路由器功能,它会进行拨号。我们的电脑可以通过这个光猫(路由器)访问互联网,但是,电信并不会给我们管理权限。也就是说,我们无法告诉路由器,把那些互联网发过来的包转发到内网的某台电脑上面去。但是,我们可以打电话给电信,要求提供公网IP。如果口才不错,又遇到好说话的客服,成功几率还是蛮高的。

另外,电信不仅有IPv4的公网IP还是IPv6的公网IP。也就是,即使拿不到IPv4的公网IP,通过IPv6也是可以直接访问内网主机的。

2.2 移动

如果你使用的是移动的宽带,不用考虑公网IP了。移动的宽带是个大局域网。很多用户共享同一个公网IP,所以,单独的用户完全无法拿到公网IP。其拓扑结构为:

flowchart LR subgraph 移动内网 subgraph 用户A内网 a1(电脑A1) b1(电脑B1) r1(用户A路由器) end subgraph 用户B内网 a2(电脑A2) b2(电脑B2) r2(用户B路由器) end r(总路由器) end i1(服务器1) i2(服务器2) i3(服务器3) a1--端口号1234-->r1 b1--端口号3456-->r1 r1-->r a2--端口号1234-->r2 b2--端口号3456-->r2 r2-->r r-.->i1 r-.->i2 r-.->i3

其中,无论用户A还是用户B的路由器都没有公网IP,只有总路由器才有公网IP。于是,我们也就没有办法通过互联网连接内网的电脑了。

但是,是的,这儿有个但是。移动的宽带是支持IPv6的,而且,移动还给每一个用户分配了公网IPv6的IP。也就是说,如果,我们通过IPv6,是有办法直接访问到内网的电脑的。可惜,很多家用或者公共路由器(比如公司或者商场之类的)并不支持IPv6。默认能支持IPv6的也就是手机的4G或者5G网络了。

2.3 联通

如果你使用的是联通的宽带,那么,你可以尝试从网上找一下联通光猫管理员账号密码。运气好的话,你可以找到,然后,有了管理员权限,也就可以关闭光猫的NAT路由功能了。然后,使用Padavan的路由器就可以实现内网穿透了。

不过,联通的IPv6支持比较落后,导致用户没有公网IPv6地址。也就是无法通过IPv6访问内网主机了。以后,会不会有变化还难说。

2.4 其他

如果是使用的那些小宽带服务上的宽带,大概率是没有公网IP的。甚至有可能没有IPv6。

3. 通用内网穿透技术

因为宽带服务商制造了诸多障碍,导致很多人无法拿到公网IP。没有公网IP也就完全没有可能通过互联网访问内网主机。那么,这种情况下有没有办法实现内网穿透呢?答案是肯定的。只是,我们需要有一个有公网IP的服务器做反向代理。

我们想一下,当存在NAT的时候,通过互联网之所以无法访问到内网主机,是因为路由器不知道将数据包转发给哪台主机。如果,我们有一个公网上的服务器。然后,我们告诉这台服务器,将所有发送给你的1234端口数据包都转发给某电脑。同时,我们再与这台服务器一直保持连接,以便让这台服务器可以随时发送回复,而这些回复其实是通过互联网发送过来的数据包。于是,也就实现了内网穿透。其时序图为:

sequenceDiagram participant a as 电脑A participant r as 公网服务器 participant i as 外网电脑/手机 a-->r: 将本地的8081端口绑定到公网服务器的端口1234 i-->>r: 发送数据到端口1234 r->>r: 查询端口1234对应的客户端 r-->>a: 将数据转发到8081端口 a->>a: 解析并处理数据 a-->>r: 发送应答数据 r-->>i: 转发应答数据

提供这类功能的软件有:frp、nps、ngrok、花生壳或者DDNSTO。其中,frp、nps和ngrok都是开源软件,你需要有一台有公网IP的云主机来安装这些服务才可以。而花生壳和DDNSTO属于商业软件,可以直接购买其服务即可,无需公网IP,也不需要云主机。你只需要在自己的电脑上安装一下他们的客户端,使用账号连接他们提供的服务器即可。另外,他们往往还会提供二级域名服务。当然,一般也是需要花钱的。

另外,网上也有一些人使用云主机部署了frp、nps或者ngrok,然后,贩卖或者免费提供其带宽供大家使用。

基于这几个软件的具体使用方法,可以查一下各自的使用手册。如果你云主机,推荐使用frp,要比另外两个更容易配置一些。如果没有云主机,可以趁双11搞特价时买一台,每年的服务费并不太高。当然,也可以直接使用花生壳或者DDNSTO。