最近一个多月我用了一下 Tailscale 这个组网工具,很喜欢。

一、组网还是不组网

在互联网的田园时代,每台能上网的计算机都能分到一个 IPv4 地址,在自己家的计算机上搭建一个网站也是一件非常容易的事情。而现代,由于 IPv4 地址的短缺,人们组建家庭或办公网络时,往往会使用路由器来做网络地址翻译(NAT)——即局域网(LAN)内的设备使用诸如 192.168.0.0/16 这样的内网网段,对外共享一个或少数几个公网 IPv4 地址。这样的部署对于一般的网上冲浪来说是够用了,但是由于没了公网可路由的地址,想要在自己家的计算机上搭建一个网站供别人访问,就变得没那么方便了。

为了解决这种需求,现代的家庭路由器一般会带有端口转发功能,即将其拿到的公网地址的某个端口转到某个内网设备的端口上。比如当外部访客访问路由器的 443/tcp 端口时,最终接收和处理请求的其实是内网某台 NAS 上的 Nginx 服务器。

除了端口转发,另一种让不在内网里的设备也能访问到内网服务的方法就是组个新的内网。比如不住在一起的朋友想要联机打游戏,那便可以通过虚拟专用网(VPN)组建一个虚拟的局域网,让两台电脑以为自己共处同一局域网下。

七年前我拥有第一台家庭服务器开始,我一直都是以端口转发作为从外界访问家中搭建的服务的主要方法,很少用到组网的方法。端口转发只要在服务端配置一下就好了,客户端无需配置,多方便啊。组网工具一个个都复杂、脆弱又不环保,花在配置组网工具上的时间真不值啊。

去年听说 Tailscale 流行起来了,我看了眼,只觉得 yet another 组网工具,没意思。后来在朋友的反复安利下,我终于试了下。发现 Tailscale 真是我用过最棒的组网工具——轻量、快捷、功能丰富、用户体验一流!他们公司的博客也写得很好,令我好感倍增。

二、VPN 的救世主 WireGuard

组网最常用的方案是 VPN,开源方案有 OpenVPN、ocserv,以及各种天鹅(FreeS/WAN、strongSwan、Libreswan、Openswan)。说实话,这些方案都很难用。

2015 年,一款名叫 WireGuard 的轻量级 VPN 软件诞生了。相比它的前辈们,它没有那些厚重的历史包袱,代码精简,但质量很高,以至于连 Linus Torvalds 都大为赞赏。2018 年的时候,这位喜欢喷人的芬兰老哥如是评价

Can I just once again state my love for it and hope it gets merged
soon? Maybe the code isn't perfect, but I've skimmed it, and compared
to the horrors that are OpenVPN and IPSec, it's a work of art.)

              Linus

相比 OpenVPN 的十万行意大利面代码,WireGuard 只用了四千行代码就实现了一个内核态的现代 VPN。

两年后的 2020 年,WireGuard 被并入 Linux 5.6 内核。

而早在 2019 年,几位 Google 出身的工程师就敏锐地察觉了 WireGuard 的潜力和商业价值,在加拿大多伦多成立了 Tailscale 公司,开始研发基于 WireGuard 的组网软件。2022 年,Tailscale 拿到 $100M 的 B 轮融资成为独角兽。

三、辐条结构与网状结构

传统的 VPN 组网方案多采用辐条结构,即一个中心服务器被多个分散在各地的客户端连接,客户端之间要交换数据的话必须把数据从服务器那里中转一下。这种结构对于客户端之间的数据交流(比如朋友间联机打游戏)并不高效,无谓地增大了数据延迟。

更适用于同一虚拟网里各个客户端之间进行数据交流的模型是网状结构(mesh),即各机之间直接相连,不用经过服务器中转。然而这样的理想模型有两个问题:

  1. 现在已经不是互联网的田园时代了,各种 NAT 让不同家庭间的机器连接变得困难
  2. N 台机器的话一共需要 N * (N - 1) 个连接/密钥对,扩展性极差

通过对不同 NAT 类型的深入研究,Tailscale 解决了问题一;感谢 WireGuard 的高性能以及合理的密钥分发机制,Tailscale 解决了问题二。

于是,mesh VPN 这种理想的模型,变得可用了。

在 Tailscale 组成的 mesh VPN 里,节点之间使用各种可能的方式,完成多重 NAT 穿越,建立 WireGuard 隧道,直接进行数据交换。由于 WireGuard 很轻量并且连接是按需建立的,所以 mesh 里的节点数量多的情况下,性能依然不会受影响。对于极少数万策尽却建立不了直接连接的情况,WireGuard 才会尝试通过他们的服务器中转。

四、Tailscale 上手

Tailscale 自己不提供 IdP——你不能创建一个 Tailscale 账号,而是只能通过外部身份,比如公司的 Active Directory 来登录。对于个人用户来说,它也提供使用 GitHub.com、Google 账户登录等选项。

Tailscale 提供各大操作系统支持。其中在 Linux 上 WireGuard 会使用内核里自带的 WireGuard 模块,而在其他平台是以用户态运行。

在 Linux 上,Tailscale 由后台常驻的 tailscaled 服务和 CLI 控制工具 tailscale 命令组成。Tailscale 网站的新手引导做得很不错,会一步步教你如何创建并加入连接两台机器,组个网,然后让它们互相 ping 对方。

Tailscale 组成的网叫 tailnet。每个 tailnet 会得到一个形如 foo-bar.ts.net 的域名,其中 foo-bar 部分是两个英语单词(不满意可以 re-roll)。

Tailscale 鼓励 mesh VPN,即在每台需要组网的设备上都装上 Tailscale,然后设备之间直连。但如果你真的有需要的话(比如家里设备真的太多了),它也提供了 subnet router 功能,即把一台设备配置成中介,把它的路由广播给别的设备。

五、不止是组网

Tailscale 不仅把组网的本职工作做好了,还带了很多贴心实用的小功能。

MagicDNS

VPN 的 DNS 一直是令人头疼的问题。Tailscale 自带 split DNS,会劫持掉本地对外的 DNS 请求由 stub resolver 处理,如果是 tailnet 域名的话就返回 tailnet 地址,否则就转发给 Tailscale 启动前的本来的 nameserver。对于 Linux 里的一万种改 /etc/resolv.conf 的方法,他们也做了详细的研究和兼容。

TLS 证书

虽然 tailnet 里的流量是加密的,但浏览器并不知道。当你访问通过 tailnet 的域名访问网站的时候,以 Chrome 为首的浏览器会显示一个不安全的警告,甚至禁用一些功能。为了解决这个问题,Tailscale 贴心地提供了帮你获取 Let's Encrypt 证书的功能。因为 ts.net 的域名是他们家的,所以用 DNS 验证的方式来拿一个证书自然是很合理的。

公网反代

既然有证书了,那其实公网流量也可以加密了?Tailscale 拿它们家自己的公网服务器提供了一个简单的反代功能,让你在 tailnet 里的 HTTPS 服务能被全世界访问到。

文件传输

两台通过 tailnet 连接的设备之间可以像 AirDrop 一样传文件

内建 HTTP 和 SSH 服务器

大概是因为 HTTP 和 SSH 是最常用的两个协议吧,Tailscale 内建了这两个服务。Tailscale 内建的 SSH 用的是 tailnet 里自己配置的 ACL 而不用到每台机器上去分发 SSH pub key;内建的 SSH 服务器甚至还带了录屏审计功能。

六、Tailscale 应用举例

tailnet 之间也是可以分享节点的。安利我 Tailscale 的朋友就把他的 Plex/Jellyfin 节点分享给了我。不把 Plex 放在公网可以有效避免 LastPass 的惨剧

虽然我的 SSH 服务都是禁止密码登录的,但被扫多了还是很烦所以装上了 Fail2ban。有了 Tailscale,可以考虑把 SSH/RDP 这类经常被扫的服务从公网上撤下来了,Fail2ban 也可以关掉了。

对于一些很难搞认证但是又想小范围分享的服务,也可以通过 Tailscale 来分享,比如 dictd 和带广告过滤的 DNS 服务器。

一些本来设计给内网用的协议,比如 NFS,可以通过 Tailscale 分享了。Tailscale 博客上有用 Steam Deck 玩另一个城市里的 NAS 硬盘里的游戏的例子

本文地址: https://wzyboy.im/post/1524.html 。转载请注明出处。


欢迎留下评论。评论前,请先阅读《隐私声明》。