使用 Headscale 和 Tailscale 搭建虚拟私有网络
为了能够远程访问主机(包括那些位于 NAT 之后的主机),可以通过搭建虚拟私有网络(也就是VPN),将这些主机连接起来。传统的 VPN 软件大构件的是Hub-and-spoke网络,所有主机(客户端)的流量经过中心VPN网关(服务器端)进行中转。那么服务器的性能和带宽,就限制了 VPN 的使用体验。而比较现代的方式,是通过网格网络(Mesh Network),构建点对点的网络。尽管此时也会有一个中心的服务器,但通常只扮演是注册中心、控制中心的角色。主机节点之间的网络传输,通过直接建立的网络,而不是通过第三方节点中转。目前此类产品的代表有 Nebula、Tailscale 等。Tailscale 在其官方网站对 Tailscale 和 Nebula 进行了比较。本文介绍如何使用 Headscale 搭建一个基础版的网格VPN。
Tailscale 简介 🔗
Tailscale 是一个在 Wireguard 之上构建的现代 VPN 软件。它使用“NAT穿越”(NAT traversal),在现有的网络之上构建了一层叠加网络。Tailscale 包括了服务器端的控制服务器,以及不同平台的客户端软件,对于用户而言,可视化的图形界面有不错的用户体验。其中一些组件是开源的,但是其控制服务器和部分客户端(Windows 和 macOS/iOS)是闭源的。
Tailscale 的一篇博客《How Tailscale works 》 阐述了它的工作原理。
Headscale 简介 🔗
Headscale 是 Tailscale 控制服务器(Control Server)的开源实现,它由 Go 语言编写,代码仓库地址为 https://github.com/juanfont/headscale。支持在 Linux、Windows、macOS 等系统部署。
也就是说,尽管 Tailscale 的控制服务器是闭源的,但可以使用 Headscale 作为开源服务器,并使用 Tailscale 的客户端,构建网格VPN。
这个大胆的想法,与 Vaultwarden 很像:Vaultwarden 是与 Bitwarden 兼容的密码管理服务器。于是可以自行搭建 Vaultwarden 服务器,然后使用 Bitwarden客户端 与其交互。
目标 🔗
本次搭建的VPN用于组建异地网络,也就是将分散在不同网络、不同物理位置的电脑连接在一起,可以互相通信。
资源准备 🔗
为了准备如下的资源:
- 一台有公网IP的 Linux 服务器。这台机器用于部署 Headscale,作为控制服务器。这个服务器必须能够被其他主机访问。
- 域名,可以使用现有域名的子域名。控制服务器会通过 HTTP 协议对外提供服务,为了安全起见,应该采用启用 SSL 证书,即使用 HTTPS 访问。需要注意的是,如果服务器在国内,那么该域名必须备案,才能访问开放了 80、443 端口的服务器。
相关软件 🔗
服务器端软件:
- Headscale:控制服务器。
- Caddy:HTTP 服务器,提供自动的 SSL 证书;作为反向代理,将请求转发给 Headscale。
客户端软件:
- Tailscale:在 Tailscale 下载相应平台的客户端即可。
搭建步骤 🔗
在服务器安装 Headscale 🔗
参考文档《Running headscale on Linux》,下载相应平台的可执行文件或者安装包,然后将作为系统服务运行。注意,由于我们使用 Caddy 作为访问入口,不应该将服务绑定到 0.0.0.0
,而应该绑定到 127.0.0.1
。对默认的配置文件 /etc/headscale/config.yaml
做如下修改:
server_url
:修改为外网访问的地址。比如域名为headscale.example.com
,那么其值为https://headscale.example.com
listen_addr
:修改为127.0.0.1:8080
务必确保 tls_letsencrypt_hostname
、tls_cert_path
和 tls_key_path
的值为空。
配置 DNS 🔗
在 DNS 提供商处,添加 DNS 记录。使得新的域名(或者二级域名)指向控制服务器。
创建 HTTP 服务器 🔗
参考 Caddy 的文档,安装好 Caddy,并作为系统服务运行。然后在其配置文件(通常位于 /etc/caddy/Caddyfile
)中,添加如下内容(将 headscale.example.com
替换为真实域名):
headscale.example.com {
reverse_proxy localhost:8080
}
重启 Caddy 服务器后,Caddy 会自动得获取 Let's Encrypt 的 SSL 证书。当可以正常访问域名下 /apple
路径时,说明配置完成。这个页面内容为在 iOS 和 macOS 配置 Tailscale 的说明。Windows 的配置说明见 /windows
地址。
在客户端安装 Tailscale 🔗
在客户端下载对应平台的 Tailscale 并安装。参考 《Tailscale CLI》 文档,确保可以在客户端主机上执行 tailscale
命令。注意,在 macOS 上配置略显复杂。
在控制服务器上创建用户 🔗
将如下的 myfirstuser
替换为用户名,然后执行:
headscale users create myfirstuser
注册节点 🔗
在客户端执行:
tailscale up --login-server <YOUR_HEADSCALE_URL>
此时自动会在控制返回一个地址,同时在浏览器打开这个地址。拷贝这个地址中的注册节点的命令,在控制服务器上执行。这个命令类似于:
headscale nodes register --user myfirstuser --key <YOUR_MACHINE_KEY>
如果注册成功,那么点击系统托盘里的 Tailscale 图标后,就会看到“Connected“的指示。
注意:Tailscale 默认的控制服务器是 Tailscale 官方的服务器。如果客户端软件没有切换到自建的服务器,那么对于 macOS 可以参考控制服务器的
/apple
页面,按照文档进行操作。
注册更多节点 🔗
如果在控制服务器上注册了多个节点,那么在 Tailscale 的 Network Devices
里,就会看到其他节点。点击节点就会复制节点的 IP,然后就可以远程访问了。
结尾 🔗
如果查阅 WireGuard 的相关资料,就会发现内容相当多,看起来相当复杂。而 Headscale 和 Tailscale 的搭建体验和使用体验却是很简单流畅,上手非常容易。在使用 Nebula 时,需要手动地给不同用户创建证书,并上传到主机节点;而使用 Headscale 时,只需要执行两行命令即可将用户注册到网络中,操作极其简单。Tailscale 的图形化界面,设计和体验看起来也不错。但在配置 Tailscale 控制器的 HTTPS 时,要么使用海外服务器,要么对域名进行备案,这让事情变得略显复杂。
本文介绍的只是 Headscale 的最简单的用法,如果要在真实的企业环境中使用,还需要考虑单点登录、权限控制、DNS、MagicDNS 等方面的配置。