近期折腾 tailscale 的一些心得

This note was originally clipped from https://blog.laisky.com/p/tailscale/?lang=zh

近期折腾 tailscale 的一些心得

Changelog:

  • 2021-11-17: 改进 tailscale 的介绍
  • 2022-3-10: 增加 ACL tags 的介绍
  • 2022-8-2: 修改 wsl、cow 的描述
  • 2023-5-19: deeper 自定义端口
  • 2023-11-15: 增加 swag 申请 HTTPS 证书
  • 2024-3-4: 修复 ACL 中放行 exit node 的设置

TailScale Serials:

Ⅰ、我的需求

最近自己装了一台高配台式机,打算当作自己的主力机器使用,笔记本电脑就作为一个移动 UI,工作都远程连到家里台式机使用。

为了满足这个需求,就需要 NAT 穿透,正好最近 mesh vpn 的概念很火,又看到 tailscale 正好对个人用户免费,于是就想试试看了。

Ⅱ、TailScale 是什么

VPN 是什么?

虽然国人看到 VPN 第一反应应该是“翻墙”,但 VPN 最初应该也是最普遍的用途应该是用来做内网打通, 这也是其名字虚拟私有网络的用意,VPN 让你可以在公开的网络线路上建立一个私有的子网, 然后将所有接入的机器都分配一个私有的内网地址,让他们可以通过 VPN 的私有网络互联。

比如最常见的需求就是,公司有一个内网办公环境,当你外出办公时,也希望你的电脑能够接入办公网络。 因为外网的机器和内网的机器不能互联,所以一般会有一个中心服务器, 所有的子节点都和中心服务器相连,然后中心服务器转发所有的流量。

这样做的缺点显而易见,首先是中心服务器(hub)会成为瓶颈。 其次,某种极端情况下,如果节点 A 和 节点 B 距离非常近,但是都离 hub 很远, 这样就会导致非常高的延迟。

那么我们就会想,能不能让节点间直接互联呢? 这就是 mesh VPN,其实现就是 wireguard。

wireguard 的每一个节点都会存储其他所有节点的信息,并且和其他所有的节点都建立 tls 连接。 如果涉及到内网穿透的话,那么你需要找到一台处于网关位置的节点(内外网都可达),将其设置为 coordinator, 扮演类似于 hub 的角色, 分发穿透内外网的流量。

wireguard 的缺点在于:

  • 配置比较繁琐
  • 维护也比较困难,增删节点都需要改动所有节点的配置

基于上述这些痛点,tailscale 做了一些改进:

  1. 在原有的 ICE、STUN 等 UDP 协议外,实现了 DERP TCP 协议来实现 NAT 穿透
  2. 基于公网的 coordinator 服务器下发 ACL 和配置,实现节点动态更新
  3. 通过第三方(如 Google) SSO 服务生成用户和私钥,实现身份认证

简而言之,我们可以认为 tailscale 是更为易用版的、功能封装更为完善的 wireguard。

Ⅲ、TailScale 能做到什么

只要你的机器可以连到公网,tailscale 可以让所有的机器连接到同一个私有子网内。 你可以像在同一个局域网里那样,随时随地的连接你的任意设备。

比如现在我的台式机和我的笔记本都登录了同一个 tailscale 账号, 它们都共享同一个 100.64/10 的子网,也就是可以随时随地的互联。 即使我的笔记本在公司内网之中,无法和家里台式机直连,但是依靠 relay 转发流量, 两者依然可以畅通无阻的直接连接。

1、传输文件

tailscale 内置 taildrop,可以在设备间传输文件,因为 tailscale 支持 android/ios/mac/windows/linux,所以实际上这也是一个很好用的全平台文件传输工具。 而且如果设备处在同一个局域网的话,传输速度也会非常快。

2、远程开发

我家台式机安装的是 windows 系统,我启用了 wsl2,然后安装了 systemd、sshd。 我放弃 wsl 了,这就是个玩具,你拿来临时跑跑脚本啥的还行,拿来当服务器就是自虐, 指不定什么时候就会遇到个什么兼容性问题,太虐了。 我换用 VMWare Player 了,对个人用户免费,用了大半年了啥问题没有。

笔记本上通过 vscode remote ssh 随时随地打开台式机上的 vscode server 进行远程开发。

这样做的一大优点是,台式机硬件的售价非常便宜,比如金士顿 32G 内存只要 880, 金士顿 1TB M2 SSD 也只要 800。WD 4TB 蓝盘不到 1 千,18 TB 黑盘也只要 2k。 也就是说,你可以用很低的成本组装一台超强配置的机器。 而同样的价钱去选购笔记本的话,只能买到很差的配置。

我认为移动办公的精髓不是你抱着一台笔记本到处移动, 而应该是无论你在哪里,只要有网,就可以用任何设备接入一个统一的办公环境。

3、代理

tailscale 节点间是点对点 tls 连接,所以实际上也可以用来做网络代理。 比如我在境外服务器上安装一个 tailscale 的节点,然后再在境外服务器上安装一个 glider 用来做 http proxy server。 那我就可以在任意一台机器上,访问境外服务器的 tailscale 子网 IP + 代理端口的形式实现 HTTP/SOCKS 代理。

配置文件示例:

一行即可:

glider 一大特点是可以配置链式代理,还可以配置多个上游(forwarder)并进行负载均衡:

利用 tailnet 的组网,配合 glider 的链式代理和负载均衡,可以实现一个非常强大、灵活的代理网络。

Ⅳ、安装、部署

参照这个官方页面安装,然后登录即可:https://tailscale.com/download

1、手动安装 derper

tailscale 提供的 relays 数量有限,而且全部在国外。 你也可以自建中继。

注:后文会提供容器安装的方式

自建中继服务器被称为 derper,是用 go 开发的,建议先安装 go 环境。

go 是预编译的,安装起来很简单,下载、解压即可。

拿 AMD64 linux 举例:

其他安装方式参考:https://golang.org/doc/install

derper 的安装方式为:

启动 derper 的参数:

  • -hostname:有效的公网域名,derper 会自动为这个域名申请 letsencrypt tls 证书。
  • -a:指定 derper 监听的 tcp 端口,默认为 443,修改为其他端口的话似乎转发流量会有问题。
  • -stun:stun 协议的 udp 端口,health check 的时候会用到。

需要注意的是,因为 derper 会申请公网 TLS 证书,如果你的服务器在国内,那么域名必须要备案。 而且由于中国封锁了 letsencrypt,所以你的 derper 在启动一会儿后,很可能会报这样的错:

上述错误表示证书自动申请失败,你可以多试几次,或者手动申请证书,然后见下文的“手动配置证书”。

顺带一提,国内的云服务器提供商,会审查 443 端口 TLS handshake 里的 SNI 信息,如果发现 SNI 域名未备案,会阻断 TLS 握手。 使用非 443 端口会有很大概率成功,但是使用非 443 端口必须使用手动配置证书的方式。

Ps. 实际用下来之后,发现建设国内 derper 实际上也有问题。虽然因为境内延迟超低,在国内做穿透的时候会非常的爽。 但是如果要做跨境穿透,因为境内的 derper 和境外的 relays 通信也有干扰,很可能导致境内外的两个节点始终无法协商到同一个 relay 上。 综合而言,如果你仅有境内穿透的需求,那么搭一个境内 derper 会很爽;但如果你要跨境,那么在境外 HK、SG 等地搭一个 derper 可能更好。

因为 tailscale 的协议时常会更新,官方建议时不时重新执行一下 go install tailscale.com/cmd/derper@main 以更新 derper server。

derper 也可以加到 systemd 里自启动:

2、容器安装 derper

docker compose 文件:

如果你的 443 已经被占用,可以使用自定义端口,会比使用默认的 443 端口稍微麻烦一点点:

  1. 需要自己申请证书,然后使用手动指定证书的方式启动 derper
  2. 需要修改 ACL,配置 derper 的端口

关于如何获取证书,此处提供一个简单的办法,可以通过 swag 自动申请 https 证书,然后挂载给 derper 使用。

Ps. 别忘了,为了让 swag 可以顺利地申请证书,你需要配置 DNS 服务器的访问 token 给 swag 使用,具体可以参考官方文档

使用自定义证书时,证书的文件名必须是: (实测都使用 PEM 格式是可以的)

  1. 证书: YOUR_DOMAIN.crt
  2. 私钥: YOUR_DOMAIN.key

注意⚠️:证书一定要直接挂载给 derper 进程,不能挂载到反向代理(如 Nginx) 上。 如果证书没有挂载到 derper 上,即使访问 derper 端口能够看到 HTTPS 加密的 derper 页面, 此时 derper 实际上也是不能正常工作的。

查看 derper 的日志,留意 serving on :12444 with TLS。 尤其是结尾的 with TLS,有这一段才说明 derper 识别并且加载了你提供的 TLS 证书。

3、配置 ACL

安装好 derper 后,需要在网页上配置服务器信息,地址在 https://login.tailscale.com/admin/acls

在其中加上一段 derpMap

其中 RegionID 必须是数字,而且必须是 9xx。

为了调试自己的 derper 是否可用,你可以先把官方的所有中继都禁用了:

在节点服务器上,需要重启 tailscaled 才能生效,win/mac 的话可以直接退出 tailscale 程序再重新打开。

linux 上,可以用:

重新进程后,可以查看 tailscale 网络的状态:

顺带一提,tailscale netcheck 实际上只 check 3478/udp 的端口, 就算 netcheck 显示能连,也不一定代表 443 端口可以转发流量。 最简单的办法是直接打开 https://x.x.x.x 的域名,如果看到如下页面,且地址栏的 SSL 证书标签显示正常可用,那才是真没问题了。

Ⅴ、ACL

1、Tags

最近学习了一下 ACL tags,它可以为机器标记 tag,然后为 tag 配置访问策略。 这可以解决 tailscale 节点一旦登录,就可以访问用户名下所有节点所有服务所导致的安全隐患。

想象有这么一个场景,我系统通过 tailscale 方便的连接一台不完全属于我的设备, 这台设备可能还有其他人也在使用。如果我仅仅是安装一个 tailscale, 那么所有能登录这台设备的人都可以通过 tailscale 连接我所有的设备。

所以我希望实现这么一个需求:我可以连接这台节点,但是这台节点不能连接我的其他节点。


目录