为什么需要自建 Tailscale 控制面
Tailscale 是我用过最顺手的异地组网工具。它基于 WireGuard 协议,把不同地点的设备组成一个虚拟局域网,不需要公网 IP,也不需要配置端口转发。无论是家里 NAS、办公室电脑,还是云服务器,安装客户端后几乎秒连。
但 Tailscale 的官方控制面是托管服务,设备认证、ACL 策略、节点路由等关键数据都走它的服务器。对于普通家庭用户来说没问题,但如果你想对数据有更完整的控制权,或者需要在国内网络环境下更稳定地管理节点,自建 Headscale 控制面就是一个性价比极高的方案。
Headscale 是 Tailscale 控制面的开源实现,用 Go 语言编写,可以部署在自己的服务器上。2025 年以来它的版本更新比较稳定,已经支持大部分 Tailscale 客户端功能,包括 exit node、subnets、MagicDNS 和 ACL。
准备工作与所需工具
我这次部署用的是一台国内 VPS(2 核 2G,Ubuntu 22.04),配合 Docker 运行 Headscale。这样做的好处是升级方便、隔离性好,不需要在宿主机上安装 Go 环境。所需工具如下:
- Docker:用于运行 Headscale 容器
- Docker Compose:编排 Headscale 和可选的 Web UI
- 一个域名 :解析到 VPS,用于 Tailscale 客户端注册控制面
- Caddy 或 Nginx:反向代理 HTTPS 到 Headscale 的 HTTP 端口
Headscale 默认走 HTTP,但 Tailscale 客户端在注册控制面时强烈建议使用 HTTPS。我用 Caddy 做了一层自动 HTTPS 反向代理,配置非常短。
部署步骤:从配置文件到容器启动
第一步是创建 Headscale 的配置目录和主配置文件。目录结构如下:
/opt/headscale/
├── config/
│ ├── config.yaml
│ └── db.sqlite
└── compose.yaml
config.yaml 里有几个关键项需要修改:
- server_url:改成你的域名,比如 https://headscale.example.com
- listen_addr:保持 0.0.0.0:8080,容器内部监听
- noise.private_key_path:Noise 协议用的私钥路径,保持默认即可
- derp.urls:如果不需要官方 DERP,可以关闭;否则保留默认 DERP 列表
compose.yaml 的内容大致如下:
services:
headscale:
image: headscale/headscale:0.25
container_name: headscale
volumes:
– ./config:/etc/headscale
– /var/run/docker.sock:/var/run/docker.sock
command: headscale serve
ports:
– “127.0.0.1:8080:8080”
restart: unless-stopped
注意我把端口绑定到 127.0.0.1:8080,外部不直接访问,而是通过 Caddy 反向代理。启动后可以用 docker compose up -d 让容器在后台运行。
创建用户与预授权密钥
Headscale 使用用户(user)作为设备分组单位。先进入容器创建一个用户:
docker exec -it headscale headscale user create myhome
然后生成预授权密钥(pre-auth key),这样新设备加入时不需要手动在控制台批准:
docker exec -it headscale headscale preauthkey create –user myhome –reusable –expiration 24h
–reusable 表示这个密钥可以注册多台设备。如果你只想注册一台,可以去掉这个参数。密钥有效期设 24 小时足够一次性的批量部署。
客户端接入与验证
在需要组网的设备上安装 Tailscale 客户端,然后执行:
tailscale up –login-server=https://headscale.example.com –authkey=xxx
Windows 和 macOS 用户可以在客户端设置里把 Login Server 改成自建域名。Android 和 iOS 需要在客户端高级选项中手动输入控制面 URL。
接入成功后,在 VPS 上查看节点列表:
docker exec -it headscale headscale node list
你会看到所有设备的 IPv4 和 IPv6 地址、在线状态、主机名。测试组网是否成功,可以用 ping 任意一个节点的 Tailscale IP。
实用进阶:子网路由与 Exit Node
Headscale 的两个高阶功能特别实用。第一个是子网路由:如果某台设备所在的局域网里还有其他设备没有装 Tailscale,你可以把这台设备配置成子网路由中继,让其他节点访问整个子网。
例如,家中有一台软路由或 Linux 设备安装了 Tailscale,你可以在上面执行:
tailscale up –advertise-routes=192.168.1.0/24
然后在 Headscale 端批准这个路由:
docker exec -it headscale headscale route approve -i “
“
第二个功能是 Exit Node。把一台节点配置成 Exit Node,其他设备就可以通过它访问互联网,适合出门在外时走回家中网络。
tailscale up –advertise-exit-node
与官方 Tailscale 的取舍
自建 Headscale 的优点是控制面数据完全私有、不需要依赖 Tailscale 官方服务、国内访问更稳定。但缺点也明显:你需要自己维护服务器、备份数据库、处理证书续期,DERP 中继性能取决于你的 VPS 带宽。
对于个人家庭组网,Headscale 已经非常够用。如果你管理的设备超过二三十台,或者需要细粒度 ACL 策略,Headscale 也能胜任,只是需要多花点时间阅读文档。总体来说,这是一套成本低、可控性强的私有网络方案,值得一试。