
Headscale · 开源自托管的 Tailscale 控制服务器 · 中文部署与使用全指南
项目仓库: https://github.com/juanfont/headscale
开源协议:BSD-3-Clause · 实现语言:Go · 容器化:Docker / OCI
镜像(Docker Hub 与 GHCR) · 数据库:SQLite ·
对外端口:TCP/443(HTTPS,客户端接入) ·
数据目录:/var/lib/headscale ·
配置文件:/etc/headscale/config.yaml
1 项目简介
Headscale(仓库名 juanfont/headscale)是
Tailscale 控制服务器(coordination server / control
plane)的开源、自托管实现。Tailscale 是构建在 WireGuard
之上的现代 VPN,它在你多台设备之间组成一张覆盖网络(overlay
network),并通过 NAT 穿透打通设备之间的直连。Tailscale
客户端本身开源,唯独控制服务器(负责交换各节点的 WireGuard
公钥、分配内网 IP、划分用户边界、路由出口)由 Tailscale Inc.
官方托管;Headscale 就是把这个"大脑"搬到你自己服务器上的开源替代品。
Headscale 官方定位很明确:为自托管爱好者、极客和小型开源组织提供一个开源、自托管的 Tailscale 控制服务器,只实现单一 Tailscale 网络(tailnet),适合个人或小团队使用,不追求复刻官方服务的全部商业能力。
非官方声明:Headscale 与 Tailscale Inc. 不存在隶属关系(官方 README 明确声明 "This project is not associated with Tailscale Inc.")。它是社区维护的开源兼容实现,客户端是官方 Tailscale 客户端;使用前请理解你自建的是一个第三方控制面,Node 注册、密钥交换数据均存放在你自己的服务器上。
1.1 核心信息一览
| 项目项 | 内容 |
|---|---|
| 项目名称 | Headscale |
| 仓库地址 | github.com/juanfont/headscale |
| 项目定位 | 开源、自托管的 Tailscale 控制服务器(WireGuard 覆盖网络协调服务) |
| 开源协议 | BSD-3-Clause |
| 实现语言 | Go |
| 数据库 | SQLite(默认) |
| 配置文件 | /etc/headscale/config.yaml(YAML) |
| 数据目录 | /var/lib/headscale(私钥、策略、SQLite 数据库) |
| 对外服务端口 | TCP/443(HTTPS,Tailscale 客户端接入,官方强烈建议) |
| 其他端口 | TCP/80(Let's Encrypt HTTP-01 校验,可选)、UDP/3478(内置 DERP 的 STUN,可选)、TCP/9090(Metrics 与调试端点,不对公网开放) |
| 容器镜像 | docker.io/headscale/headscale:<VERSION>、ghcr.io/juanfont/headscale:<VERSION> |
| 系统入口 | headscale serve(服务进程) /
headscale <子命令>(CLI 管理) |
1.2 适用场景
- 想在自己多台服务器、家里电脑、手机之间组一张私有内网,而不是把控制面交给第三方托管。
- 需要给团队 / 家庭多台设备打通 SSH、内网服务、共享盘,而不想维护传统 VPN(OpenVPN / WireGuard 手动组网)的复杂密钥。
- 对数据主权敏感:节点密钥、注册信息、访问策略全部留在自己服务器的 SQLite 里。
- 想在实验室、小型开源组织里跑一个单 tailnet,集中管理用户与设备。
1.3 能力边界(官方口径)
- 官方明确:Headscale 是一个窄范围、单一 tailnet 的实现,面向自托管与小型组织,不承诺复刻 Tailscale 官方控制面的全部功能。
- 官方文档建议:生产环境应通过 HTTPS/TCP 443 对外提供服务;用 HTTP 或其他端口也能跑,但官方强烈不建议。
- 官方同时声明:不支持、也不鼓励用反向代理和容器来运行 Headscale(容器部署页由社区维护、未经开发者核验,可能过时)。
2 功能特性
- 自托管控制面:自己持有 WireGuard 公钥交换点、IP 分配、用户边界与路由出口,数据不出自己的服务器。
- 官方 Tailscale 客户端直接接入:Linux / macOS /
Windows / iOS / Android 客户端通过
tailscale up --login-server <你的地址>即可接入自建 Headscale。 - 多用户与节点管理:
headscale users create/list创建用户,节点(machine)挂在用户下,一个用户可挂多台设备。 - 节点注册两种路径:Web
认证(浏览器打开授权页,服务端用
headscale auth register --user <USER> --auth-id <AUTH_ID>批准)或预授权密钥(headscale preauthkeys)。 - 访问策略(policy):可定义节点间、用户间的访问边界与共享规则。
- 内置 DERP / STUN(可选):打洞失败时的中继通道,对应 UDP/3478(STUN)与 TCP/443。
- Metrics 与调试端点:TCP/9090 暴露指标,默认不对外。
- Web UI 集成:可对接第三方 Web 管理界面(官方文档
ref/integration/web-ui/)。 - 配置校验工具:
headscale configtest用于启动前校验 YAML 配置。
3 官方界面预览
Headscale 本身是一个后台服务,没有自带 Web
管理界面;上面封面是项目官方标识。日常操作通过 headscale
命令行完成,Web 界面属于可选的第三方集成(官方文档单独成章)。
4 官方跳转链接汇总
| 类别 | 链接 | 说明 |
|---|---|---|
| 仓库主页 | https://github.com/juanfont/headscale | 源码、README、配置示例 |
| 官方文档(稳定版) | https://headscale.net/stable/ | 安装、配置、使用完整文档 |
| Release 下载 | https://github.com/juanfont/headscale/releases | Linux 二进制与 DEB 包 |
| 容器镜像 | ghcr.io/juanfont/headscale | GHCR 镜像 |
| 配置示例 | config-example.yaml | 各版本配置模板 |
| Issues | https://github.com/juanfont/headscale/issues | Bug 反馈与讨论 |
| Discord 社区 | https://discord.gg/c84AZQhmpx | 官方聊天社区 |
5 前置要求与服务器配置
5.1 软件前提
- 一台带公网 IP 的服务器:官方要求 Headscale 所在服务器有公网 IP,推荐同时具备公网 IPv4 与 IPv6(双栈)。
- 现代 Linux 或 BSD 操作系统:DEB 包官方支持 Ubuntu 22.04 及更新、Debian 12 及更新。
- HTTPS/TCP 443 可达:Tailscale 客户端在某些情况下默认假设控制面是 443 端口的 HTTPS;官方强烈建议生产环境按此部署。
- 独立本地用户:Headscale 官方设计由专用本地用户(如
headscale)以 systemd 服务运行。 - 少量命令行基础:官方文档明确要求使用者具备基本的命令行配置与运维能力。
5.2 服务器建议
| 项目 | 建议 |
|---|---|
| 公网 IP | 必备(推荐双栈 IPv4 + IPv6) |
| 系统 | Ubuntu 22.04+ / Debian 12+,或现代 BSD |
| 内存 | 轻量服务,1 GB 起步即可 |
| 磁盘 | SQLite 数据库 + 配置,占用极小 |
5.3 端口分配
| 端口 | 协议 | 对外 | 用途 |
|---|---|---|---|
| 443 | TCP | 是 | HTTPS,Tailscale 客户端接入(强烈建议) |
| 80 | TCP | 是 | Let's Encrypt HTTP-01 校验,仅在使用内置 ACME 时需要 |
| 3478 | UDP | 是 | STUN,仅在内置 DERP 启用时需要 |
| 9090 | TCP | 否 | Metrics / 调试端点,仅本机 |
安全提示:9090 指标端点不要暴露公网;443 建议直接由 Headscale 监听或置于受控反向代理之后。
6 方式一:DEB 包安装(官方推荐)
适用于 Debian / Ubuntu 服务器。官方推荐这种方式,因为包会自动创建专用运行用户、提供默认配置并附带 systemd 服务文件。
# 1. 到 Release 页查最新版本号(不要加 v 前缀)
# https://github.com/juanfont/headscale/releases/latest
HEADSCALE_VERSION="X.Y.Z" # 替换为实际版本
HEADSCALE_ARCH="amd64" # 或 arm64
# 2. 下载 .deb 包
wget --output-document=headscale.deb \
"https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
# 3. 安装
sudo apt install ./headscale.deb
# 4. 编辑配置(示例配置在 /usr/share/doc/headscale/examples/config-example.yaml)
sudo nano /etc/headscale/config.yaml
# 5. 重启并查看状态
sudo systemctl restart headscale
sudo systemctl status headscale配置文件里务必把 base_url 改成你自己的域名(如
https://headscale.example.com),并确保证书有效。改完后用
headscale configtest 校验再重启。
7 方式二:容器运行(社区文档,非官方主推)
注意:官方明确说容器运行页由社区维护、未经开发者核验,可能过时;官方主推是 DEB 包或裸二进制。
# 1. 建目录
mkdir -p ./headscale/{config,lib}
cd ./headscale
# 2. 把对应版本的 config.yaml 放进 ./config/
# 3. 启动(默认只绑定本机回环;需要对外时把 127.0.0.1 换成 0.0.0.0)
docker run \
--name headscale \
--detach \
--read-only \
--tmpfs /tmp \
--tmpfs /var/run/headscale \
--volume "$(pwd)/config:/etc/headscale:ro" \
--volume "$(pwd)/lib:/var/lib/headscale" \
--publish 127.0.0.1:8080:8080 \
--publish 127.0.0.1:9090:9090 \
--health-cmd "CMD headscale health" \
docker.io/headscale/headscale:<VERSION> \
serve等价的 docker-compose:
services:
headscale:
image: docker.io/headscale/headscale:<VERSION>
restart: unless-stopped
container_name: headscale
read_only: true
tmpfs:
- /var/run/headscale
ports:
- "127.0.0.1:8080:8080"
- "127.0.0.1:9090:9090"
volumes:
- <HEADSCALE绝对路径>/config:/etc/headscale:ro
- <HEADSCALE绝对路径>/lib:/var/lib/headscale
command: serve
healthcheck:
test: ["CMD", "headscale", "health"]验证:docker logs --follow headscale、docker ps、curl http://127.0.0.1:8080/health。容器镜像是
distroless 无 shell,需要调试时用 -debug 变体镜像(如
docker.io/headscale/headscale:x.x.x-debug)。
8 配置项说明
- 加载顺序:YAML 配置文件,依次搜索
/etc/headscale、$HOME/.headscale、当前工作目录下的config.yaml。 - 指定路径:用命令行参数
-c/--config或环境变量HEADSCALE_CONFIG指定。 - 示例配置:从 Release 对应 tag 下载
config-example.yaml(务必选与你安装版本相同的 tag,main 分支可能含未发布改动)。 - 关键字段:
base_url(你的对外域名,客户端据此连接)、unix_socket(默认 unix socket 路径,包安装下建议/var/run/headscale/headscale.sock)、数据库位置、TLS 证书、DERP 开关。 - 校验:改完配置先跑
headscale configtest。
9 常用运维命令
# 查看帮助
headscale help
headscale <COMMAND> --help
# 用户管理
headscale users create <USER>
headscale users list
# Web 认证模式批准节点(客户端 tailscale up 后会给出 AUTH_ID)
headscale auth register --user <USER> --auth-id <AUTH_ID>
# 节点与预授权密钥
headscale nodes list
headscale preauthkeys create --user <USER>
# 容器内执行命令
docker exec -it headscale headscale help
docker exec -it headscale headscale users list
# 服务管理(systemd)
sudo systemctl restart headscale
sudo systemctl status headscale注意:默认只有 headscale 用户或 root 能访问
unix socket;普通用户执行 CLI 时用 sudo、切到 headscale
用户,或把自己加入 headscale
组。验证连通:headscale users list 不报错即 socket
权限正常。
10 常见故障排查
- 客户端连不上控制面:确认服务监听在 443 且为有效
HTTPS;浏览器访问
https://headscale.example.com/health应返回正常。官方强烈建议 443 端口 HTTPS,非标端口 / 纯 HTTP 在部分客户端上会异常。 - 改完配置不生效:YAML 改完务必
headscale configtest校验,再systemctl restart headscale;容器部署看docker logs --follow headscale。 - CLI 报 socket 权限错误:当前用户无权访问
/var/run/headscale/headscale.sock,用 sudo 或加入 headscale 组。 - 容器内无 shell 无法调试:换用
-debug变体镜像(含 Busybox),再docker exec -it <容器> sh。 - NAT 打洞失败、设备掉线:检查是否需要启用内置 DERP 中继与 UDP/3478 STUN 端口放行。
- 版本与配置不匹配:官方反复强调,示例配置必须选与已安装版本一致的 GitHub tag,main 分支配置可能超前。
11 风险与合规说明
- Headscale 是 BSD-3-Clause 许可的社区项目,与 Tailscale Inc. 无隶属关系;它不是官方产品,兼容性与新特性跟进存在滞后风险。
- 自建控制面意味着节点 WireGuard 密钥、注册信息、访问策略由你自己保管,需自行承担服务器安全、证书续期、备份(SQLite 与数据目录)责任。
- 请仅在你自己拥有或已获授权的设备上部署客户端;将内部服务暴露到网络时做好访问策略(policy)与鉴权。
- 本文命令、端口、路径均来自 Headscale 官方文档与仓库 README,随版本演进可能调整,以你部署版本对应 tag 的官方文档为准。