从公网访问内网的常用方法和个人经验

通过公网访问某个只在内网的机器,或者把内网服务器的某个端口暴露到公网,是个十分常见的需求,也就是常说的内网穿透。 不管从事计算机相关工作还是自己瞎折腾,或多或少会遇到这种场景。回顾一下,自己为了各种需求也尝试过各种不同的方法,在这里总结一下各种方法的原理和过程中积累的经验。

用过的方法

端口映射

原理:在网关路由器或防火墙上配置将公网IP的某个端口映射到内网某个机器的某个端口。普通家庭路由器的设置页面也会有这个功能(尽管多数家庭宽带没有公网IP)。一般来说网管才能有配置这个的权力,一般人需要提出申请,批准后才能用。

使用条件:比较高的网络管理权限,或者需要提出申请和审批。

场景:我用这个方法的场景是工作时搭在内网的服务的要跟外面的人对接。

评价:比较正规的方式。但是如果自己暴露到公网的服务不靠谱,还是会有被黑进内网的风险。

VPN

原理:个人感觉这个词在普通人嘴里偏离了它最原始的作用,总是跟魔法上网联系上。让我回顾一下大学课程,看看 VPN 到底是个什么东西。

VPN (Virtual Private Network) 利用隧道协议,使用户通过公用网络传递内部网络的消息,就好像直接连接到内部网络一样远程访问内网的资源。因为要穿过公网,VPN协议通常会比较注重安全性和保密性。 其中最新的应该是一年前刚被加到 linux 内核里的 WireGuard,主要解决的问题是之前的协议比较复杂难配置。 VPN 是一个非常大的话题,光是分类就有好多种分法,而且我都是从用户角度使用,没有自己研究和折腾过相关协议,原理方面这里无法细说。

从用户的角度,使用方法一般是跟IT部门申请一个帐号和想要访问的资源,打开软件登录或配置下网络,就可以通过公网访问内网资源了,比如特定服务器的特定端口。

VPN协议一般都会给隧道加密,之前常被用作魔法上网,但如今魔法上网最重要的不仅是加密而是不要被识别。尽管现在的常见魔法上网软件的原理基本都与 VPN 无关了,普通人还是会习惯性用 VPN 称呼这类软件,忽略了 VPN 的其他用途。去年的疫情有让人意识到 VPN 的正常使用方式从而遏制这个叫错的趋势吗?身边统计学,没有。

使用条件:学校/公司的IT部门提供这个服务,可能需要提出申请和审批。

场景:我用这个方法的场景是疫情期间在家远程干活。

评价:也是实现访问内网比较正规的一种方式。IT部门一般会直接买相关公司比如深信服的现成服务来用,一般也会提供比较完善的权限控制。被黑进内网的主要责任在软件的漏洞,个人只要保管好自己的密码或者密钥就可以了。

SSH

原理:需要一台在同一个内网又有公网IP的设备,这台设备一般被称作跳板机或堡垒机。简单来说就是你通过 SSH 连接跳板机,它再帮你连接内网其他机器,在你看来就好像直接连接到了内网机器一样。最简单的使用方式就是通过 ssh 的 -J 选项登录内网机器。

除了登录外,SSH 也可以提供端口转发。一般分为本地端口转发、远程端口转发和动态端口转发。 介绍下这几种端口转发的原理。假设你的电脑是A,跳板机B,内网机器C。本地端口转发是在A本地绑定一个端口X,A访问本地的X,经过B转发到C,相当于在访问C的一个端口Y。本地端口转发和远程端口转发的关系可以类比代理和反向代理的关系。动态端口转发就是去掉了C的Y这个限制,A告诉本地的X要访问的地址和端口,B来帮A访问。B在这里成了代理(Proxy)服务器。

如果还是不理解,一个比较好用的 SSH 客户端 MobaXterm 的 SSH 隧道配置界面有一个很形象的动画可供参考。

顺便一说,现在流行的魔法上网软件的原理基本都可以看成是自己造了个加密协议替代 SSH 然后实现上面所说的动态端口转发。

使用条件:一台在同一个内网又有公网IP的设备

场景:我用这个方法的场景是偶尔在外面远程登录内网机器干活。

评价:这个方法相对还是比较安心的,安全性由 SSH 来保证,这种基础协议和软件出问题的可能性更小,即使出了问题也更受到大家关注,补丁更及时。你只需要管好你的密码或密钥。

frp

frp 是一个 go 写的非常有名的可用来内网穿透的开源软件,本质是一个反向代理。

原理:虽然外面访问不到内网机器,但内网机器一般可以主动访问公网,因此可以用一台有公网IP的设备做反向代理。在内网机器通过运行客户端 frpc 主动与公网机器建立连接后,运行在公网机器的服务端 frps 将外面对公网机器端口A的请求转发到内网机器的端口B,实现将内网的一个端口映射到公网IP的一个端口。

使用条件:一台有公网IP的设备

场景:我用这个方法的场景是临时有内网的简单服务要外面访问。

评价:懒得走申请端口映射的流程时可以拿它凑合一下,但是有相对较大的安全风险。一旦被暴露的服务不靠谱,有人从那个端口黑进内网,所有的锅都要自己背。

zerotier

zerotier 也是内网穿透常用的开源软件,但跟上面 frp 的原理完全不一样。它可以用来异地组网,跟 VPN 有点像但提供了P2P通信的功能。同时它也有点 SD-WAN 那味,可以中心化地管理虚拟网络里的节点。

使用方式是从它的官网注册帐号,创建一个网络。之后每台设备安装客户端,加入网络。之后每台设备会多出一个虚拟网卡,互相之间通过这个网卡在公网上通信,从而建立一个自己的虚拟局域网。由于每台申请加入的设备都要在管理页面上手动同意,经过公网的流量也会加密,所以看起来会相对安全。

原理:研究了一下官方文档。一个 zerotier 网络由 PLANET,MOON,LEAF 三种节点组成。LEAF 是普通节点,也就是需要通过这个网络互相通信的一台设备。PLANET 是根服务器,跟 DNS 里的根服务器类似,个人感觉也有点像 SDN 里的控制器。根服务器数量是确定的,由这家公司免费提供。每个其他类型的节点想要互相通信都必须先与根服务器通信。每个 LEAF 节点也可以通过配置成为 MOON,主要功能是做中继,加速通信路径的建立。

实际场景中,比如我的电脑A,内网机器B 加入了同一个 zerotier 网络。一开始他们之间并没有路径,A 发包给 B 要先与根服务器建立连接,帮它找到 B 在哪里。得知双方的消息后,根服务器会帮助他们NAT打洞,一旦打洞成功,AB之后的通信就是P2P的了,不再有根服务器参与;否则就只能通过根服务器转发流量。如果 A 和 B 与根服务器之间时延都比较大,那将非常痛苦。这时,如果网络里有一个 MOON 节点帮助转发,速度就会快一些。

使用条件:最好有一台有公网IP的设备,没有也能用。

场景:我用这个方法的场景是有内网服务要外面特定的几个设备访问。

评价:给我感觉还不错,因为建立的私网需要给每个设备点同意才能开始通信,看起来比frp这种完全暴露在公网要安全。但是 zerotier 的中心化程度还是比较高的,使用时强制要连接他自己的根服务器,如果没有一台国内服务器做 moon 节点中继的话效果并不好。 如果 zerotier 能很方便地自建根服务器完全摆脱这个公司提供的服务,在我看来那将绝杀。 此外还有一些类似的组网软件,如 nebula, n2n, tinc,自己没用过不评价。

其他现成服务

除了 zerotier,也有些国内公司会卖现成的服务,如花生壳、蒲公英,只是听说过没用过,无法给出评价。

经验

安全,安全,还是他妈的安全!

如果有相关的需求,在选择方法时安全一定是最优先考虑的。一旦操作不当内网就遭重了。以我的经验来说,内网还是挺脆弱的,弱密码到处都是。如果只是遇到扫描弱密码然后大张旗鼓挖个矿的脚本小子倒还好,大不了重装。如果遇到润物细无声悄悄进来搞事的就惨了,一般人很难发现。

插句题外话,可以发现本文讲到的内容经常提到转发、代理这样的字眼,忍不住让人联想到某个为在我国网民中推广各种网络技术做出了巨大贡献的重要网络设施。仔细想想,这两件事其实就是非常类似,只是内外上的区别。事实上,本文提到的其中一些技术在早些年确实是魔法上网的常用手段,不过在攻守双方的不断进步中因为特征太明显被抛弃了。

更新 21-11-30

后来尝试了 wireguard 以及 基于 wireguard 的 tailscale,它们都强调配置的简单,事实上确实都很简单,用起来体验也不错。

特别强调一下 tailscale,如果我没理解错这篇博客的话,可以看作是若干 wireguard peer 集中交换公钥并且提供了 NAT 打洞。目前我远程访问内网基本都是用它,因为刚好我宿舍的网和我的内网服务器能够成功打洞,延迟也很低。如果打洞不成还是要用它提供的服务器中转,体验会差一些。