Ubuntu 22.04 安装 Headscale 指南

Ubuntu 22.04 从零安装 Headscale v0.29.5:官方二进制与 deb 包两种方案、systemd 托管与开机自启、Tailscale 客户端双路径注册实测(CLI 批准与预授权密钥)、隧道互通验证与完整卸载流程,命令回显逐条实测采集。

HeadscaleHeadscale2026/10/18

Ubuntu 22.04 安装 Headscale 指南

‍‍​​‌​> 目标:在 Ubuntu 22.04 服务器上从零安装 Headscale v0.29.5(Tailscale 控制面自托管实现),完成二进制安装、systemd 托管、开机自启、配置修改与验证,并用第二台 Ubuntu 22.04 机器安装 Tailscale 客户端实测两条节点注册路径(CLI 批准注册与预授权密钥注册),最后给出卸载清理方法。全文命令与回显均在 Ubuntu 22.04.5 实测环境逐条执行采集,Headscale 版本 v0.29.5、Tailscale 客户端 1.104.1。

一、环境信息

本文实测环境与关键可复现信息如下:

  • 服务端操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • 服务端 IP:192.168.32.2(下文所有 server_url 与客户端指向均以它为准)
  • 服务端组件:Headscale v0.29.5(commit 0f7d1e536bed9f01dd7161f7637af19bb0908335,构建时间 2026-10-13,Go 1.26.8 编译)
  • 客户端操作系统:Ubuntu 22.04.5 LTS(x86_64),两台,IP 分别为 192.168.32.3(node1)、192.168.32.4(node2)
  • 客户端组件:Tailscale 1.104.1(官方 apt 仓库安装)
  • 服务端口:HTTP 8080(客户端与 Web 认证入口)、Metrics 9090(默认仅本机)、gRPC 50443(未配 TLS 证书时不监听,管理走本地 Unix socket)
  • 数据目录:/var/lib/headscale(SQLite 数据库、Noise 私钥)
  • 配置目录:/etc/headscale
  • 二进制位置:/usr/local/bin/headscale(方案 A)/ /usr/bin/headscale(方案 B)

二、前置条件

安装前确认以下条件,避免中途卡住:

  1. 一台 Ubuntu 22.04 服务器(服务端),具备 sudo/root 权限;客户端为另一台 Ubuntu 22.04 机器(或同一台也可演示,但生产中建议分离);
  2. 网络可达性:服务端需能访问 GitHub(下载安装包);客户端需能访问 GitHub(添加 apt 仓库密钥)与服务端 8080 端口;
  3. 基础工具:curl、systemd(Ubuntu 22.04 自带)。服务端建议提前安装 sqlite3(备份恢复用):
apt-get update && apt-get install -y curl sqlite3

实测输出(服务端,工具已装时确认版本即可):

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.20
3.37.2 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1
  1. 防火墙放行:客户端接入需要服务端开放 8080/tcp;启用内嵌 DERP 时还需 3478/udp。本文按最简形态(放行 8080)演示。

⚠️ 注意:若服务器访问 GitHub 慢或失败,可配置 HTTP 代理(如 https_proxy=http://<代理地址>:<端口> 环境变量)或改用国内镜像加速后重试下载。

三、版本选型说明

Headscale 更新较快,选型时把握三点:

  • 取最新稳定版:从 https://github.com/juanfont/headscale/releases 获取最新 Release。本文实测时最新稳定版为 v0.29.5(构建于 2026-10-13),与前一版 v0.29.4(构建于 2026-09-23)约间隔 3 周,0.29 系列 0.29.0~0.29.5 连续 6 个稳定发布;
  • 客户端版本下限:v0.29.5 服务端启动日志明确 Clients with a lower minimum version will be rejected minimum_version=v1.80,即接入的 Tailscale 客户端不得低于 1.80(本文实测 1.104.1 通过);
  • 文档与版本对齐:官方 README 提醒查看文档要选与所用版本一致的 tag,安装配置时建议直接下载 v0.29.5 tag 的 config-example.yaml,避免用到 main 分支的未发布配置结构。

版本对照表(本文实测采集):

项目版本/值来源
Headscalev0.29.5GitHub Releases 最新稳定版
Tailscale 客户端1.104.1pkgs.tailscale.com stable(jammy)
服务端要求客户端下限≥ 1.80服务端启动日志实测
配置样例config-example.yaml(v0.29.5 tag,494 行)GitHub 仓库 tag 下载

四、方案 A:官方二进制安装 + systemd 托管(推荐)

方案 A 是官方安装文档(https://headscale.net/stable/setup/official/ )推荐形态:下载 Release 二进制、创建专用系统用户、手写 systemd 服务文件。优点是路径清晰、文件位置可控、升级只需覆盖二进制;缺点是需要手工创建用户与服务文件。

4.1 下载二进制并校验

cd /tmp
curl -fsSL -O https://github.com/juanfont/headscale/releases/download/v0.29.5/headscale_0.29.5_linux_amd64
curl -fsSL -O https://github.com/juanfont/headscale/releases/download/v0.29.5/checksums.txt
ls -l headscale_0.29.5_linux_amd64 checksums.txt
grep linux_amd64 checksums.txt
sha256sum headscale_0.29.5_linux_amd64

实测输出:

-rw-r--r-- 1 root root      767 Oct 17 21:41 checksums.txt
-rw-r--r-- 1 root root 52510882 Oct 17 21:41 headscale_0.29.5_linux_amd64
9e8ec12a65229435863a2cdf5082853c282808e845efd3a1f0b0c02b8f84d723  headscale_0.29.5_linux_amd64.deb
e979d27fe17d924d33bb6ab7504f6338d0635989a0cfdcfbc0ceb637dbcbe980  headscale_0.29.5_linux_amd64
e979d27fe17d924d33bb6ab7504f6338d0635989a0cfdcfbc0ceb637dbcbe980  headscale_0.29.5_linux_amd64

最后两行分别是官方 checksums.txt 中的期望值与本地计算的 sha256,两者一致(e979d27f...)说明下载完整。安装到 PATH 并确认版本:

install -m 0755 /tmp/headscale_0.29.5_linux_amd64 /usr/local/bin/headscale
headscale version

实测输出:

headscale version v0.29.5
commit: 0f7d1e536bed9f01dd7161f7637af19bb0908335
build time: 2026-10-13T12:35:52Z
built with: go1.26.8 linux/amd64

4.2 创建系统用户与目录

useradd --system --home-dir /var/lib/headscale --shell /usr/sbin/nologin headscale
mkdir -p /etc/headscale /var/lib/headscale /var/run/headscale
chown -R headscale:headscale /var/lib/headscale /var/run/headscale
id headscale

实测输出:

uid=999(headscale) gid=999(headscale) groups=999(headscale)

三个目录的分工:/etc/headscale 放配置,/var/lib/headscale 放数据库与密钥(服务运行时的家目录),/var/run/headscale 放 CLI 用的 Unix socket(由 systemd 的 RuntimeDirectory 自动管理权限)。

4.3 下载并修改配置文件

从 v0.29.5 tag 下载官方示例配置(494 行,含逐项注释),改掉本机回环相关的三处默认值:

curl -fsSL https://github.com/juanfont/headscale/raw/v0.29.5/config-example.yaml -o /etc/headscale/config.yaml
wc -l /etc/headscale/config.yaml

实测输出:

494 /etc/headscale/config.yaml

示例配置默认全部监听 127.0.0.1(本地试用形态),需要改成对外可访问并指定客户端连接地址。用 sed 修改四处(也可手工编辑):

sed -i 's|server_url: http://127.0.0.1:8080|server_url: http://192.168.32.2:8080|' /etc/headscale/config.yaml
sed -i 's|listen_addr: 127.0.0.1:8080|listen_addr: 0.0.0.0:8080|' /etc/headscale/config.yaml
sed -i 's|grpc_listen_addr: 127.0.0.1:50443|grpc_listen_addr: 0.0.0.0:50443|' /etc/headscale/config.yaml
sed -i 's|base_domain: example.com|base_domain: tailnet.example.com|' /etc/headscale/config.yaml

验证修改结果:

grep -nE '^(server_url|listen_addr|metrics_listen_addr|grpc_listen_addr)|base_domain:' /etc/headscale/config.yaml

实测输出:

13:server_url: http://192.168.32.2:8080
19:listen_addr: 0.0.0.0:8080
24:metrics_listen_addr: 127.0.0.1:9090
34:grpc_listen_addr: 0.0.0.0:50443
330:  base_domain: tailnet.example.com

四处关键项的含义:

参数修改前修改后说明
server_urlhttp://127.0.0.1:8080http://192.168.32.2:8080客户端连接控制面的对外地址,必须是客户端可达的 IP 或域名
listen_addr127.0.0.1:80800.0.0.0:8080HTTP 监听地址,0.0.0.0 才接受外部连接
grpc_listen_addr127.0.0.1:504430.0.0.0:50443远程 gRPC 管理地址;未配 TLS 证书时该端口实际不会监听,CLI 走本地 Unix socket
base_domainexample.comtailnet.example.comMagicDNS 域名后缀,必须与 server_url 域名不同

⚠️ 注意:server_url 与客户端实际访问地址必须一致,否则客户端在注册后会因控制地址不匹配而连不上。生产环境建议使用域名加 HTTPS(Headscale 支持自动 ACME 或自带证书,详见《Headscale 配置参数详解》)。

4.4 编写 systemd 服务文件

创建 /etc/systemd/system/headscale.service(全文如下):

cat > /etc/systemd/system/headscale.service <<'EOF'
[Unit]
Description=headscale controller
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5
RuntimeDirectory=headscale
RuntimeDirectoryMode=0750

[Install]
WantedBy=multi-user.target
EOF

逐项说明:After/Wants=network-online.target 保证网络就绪后再启动;User/Group=headscale 以专用低权用户运行;ExecStart=/usr/local/bin/headscale serve 是服务主进程(必须与二进制实际路径一致);Restart=always + RestartSec=5 让进程异常退出后 5 秒自动拉起;RuntimeDirectory=headscale 让 systemd 自动创建并清理 /var/run/headscale(权限 0750)。

加载并设置开机自启:

systemctl daemon-reload
systemctl enable headscale
systemctl start headscale

实测输出(enable 时):

Created symlink /etc/systemd/system/multi-user.target.wants/headscale.service → /etc/systemd/system/headscale.service.

4.5 启动验证

systemctl is-enabled headscale
systemctl is-active headscale
journalctl -u headscale --no-pager -n 10 | tail -8

实测输出:

enabled
active
Oct 17 21:48:24 hs-controller headscale[2745]: 2026-10-17T21:48:24Z INF no private key file at path, creating... path=/var/lib/headscale/noise_private.key
Oct 17 21:48:24 hs-controller headscale[2745]: 2026-10-17T21:48:24Z INF Opening database database=sqlite3 path=/var/lib/headscale/db.sqlite
Oct 17 21:48:24 hs-controller headscale[2745]: 2026-10-17T21:48:24Z INF starting headscale commit=0f7d1e536bed9f01dd7161f7637af19bb0908335 version=v0.29.5
Oct 17 21:48:24 hs-controller headscale[2745]: 2026-10-17T21:48:24Z INF Clients with a lower minimum version will be rejected minimum_version=v1.80
Oct 17 21:48:25 hs-controller headscale[2745]: 2026-10-17T21:48:25Z INF HA subnet router health probing enabled interval=10000 timeout=5000
Oct 17 21:48:25 hs-controller headscale[2745]: 2026-10-17T21:48:25Z INF listening and serving HTTP on: 0.0.0.0:8080
Oct 17 21:48:25 hs-controller headscale[2745]: 2026-10-17T21:48:25Z INF listening and serving debug and metrics on: 127.0.0.1:9090

首次启动日志说明:Noise 私钥与 SQLite 库自动创建、最低客户端版本 1.80、HTTP 监听 0.0.0.0:8080、metrics 监听 127.0.0.1:9090。继续做 HTTP 探活与本机端口确认:

curl -s http://127.0.0.1:8080/health
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/

实测输出:

{"status":"pass"}
200

至此服务端安装完成。方案 B(deb 包)安装同样可用,见下一章;两方案对比见 4.6 之后的「方案对比与选择建议」。

五、方案 B:官方 deb 包安装

官方 Release 同时提供 .deb 包(headscale_0.29.5_linux_amd64.deb,约 20MB),内置 systemd 服务文件与默认配置,适合快速部署。安装命令与实测输出:

cd /tmp
curl -fsSL -O https://github.com/juanfont/headscale/releases/download/v0.29.5/headscale_0.29.5_linux_amd64.deb
ls -l headscale_0.29.5_linux_amd64.deb
dpkg -i headscale_0.29.5_linux_amd64.deb

实测输出:

-rw-r--r-- 1 root root 20037054 Oct 17 22:12 headscale_0.29.5_linux_amd64.deb
(Reading database ... 7353 files and directories currently installed.)
Preparing to unpack headscale_0.29.5_linux_amd64.deb ...
Unpacking headscale (0.29.5) ...
Setting up headscale (0.29.5) ...
Created symlink /etc/systemd/system/multi-user.target.wants/headscale.service → /lib/systemd/system/headscale.service.

deb 包完成的工作:安装二进制到 /usr/bin/headscale、生成 /etc/headscale/config.yaml 默认配置、安装自带 systemd 服务并自动 enable。查看文件布局与版本:

dpkg -L headscale
headscale version

实测输出(文件布局节选):

/etc/headscale/config.yaml
/usr/bin/headscale
/usr/lib/systemd/system/headscale.service
/usr/share/doc/headscale/examples/config-example.yaml
/var/lib/headscale
headscale version v0.29.5
commit: 0f7d1e536bed9f01dd7161f7637af19bb0908335
build time: 2026-10-13T12:35:52Z
built with: go1.26.8 linux/amd64

与方案 A 的三点差异必须知道:

  1. 二进制路径不同:/usr/bin/headscale(方案 A 为 /usr/local/bin/headscale),deb 自带服务文件的 ExecStart 指向 /usr/bin/headscale serve;
  2. 配置仍是默认值:/etc/headscale/config.yaml 中 server_url 与 listen_addr 均为 127.0.0.1,安装后必须按 4.3 节同样的方式修改,否则客户端无法接入;
  3. 服务文件是官方加固版:包含 ProtectSystem=strict、SystemCallFilter、StateDirectory=headscale 等安全加固项,并支持 ExecReload=/usr/bin/kill -HUP $MAINPID(reload 重载配置)。

deb 方案的启动与验证命令与方案 A 相同(systemctl is-active headscale、curl http://127.0.0.1:8080/health),这里不再重复;唯一注意点是若端口被占用启动失败,先处理端口再 systemctl restart headscale。

六、方案对比与选择建议

维度方案 A:二进制 + systemd方案 B:官方 deb 包
版本任意 Release 版本任意 Release 版本(同页提供 .deb)
安装方式手工下载 + 建用户 + 写服务文件dpkg -i 一条命令
二进制位置/usr/local/bin/headscale/usr/bin/headscale
systemd 服务来源自写(基础版,本文 4.4 节)包内置(加固版,含 ProtectSystem 等)
升级方式覆盖二进制 + restartdpkg -i 新版 .deb 覆盖
卸载方式删文件/用户/目录(本文第十章)dpkg -r headscale(配置残留需手工清)
适用场景需要精细控制路径与参数、无 root 亦可半手工部署追求快速标准化,接受包管理器管理

选择建议:能联网的标准化 Ubuntu 环境优先方案 B(快捷且自带加固);需要自定义安装路径、或在不方便使用包管理的最小化系统上,用方案 A。两方案的配置文件、注册流程、运维命令完全一致,后续章节对两者通用。

七、Tailscale 客户端接入注册

Headscale 装好后只是空网络,需要节点接入。本章在客户端 Ubuntu 22.04 上安装官方 Tailscale 客户端,并实测两条注册路径:路径 A「Web 注册 URL + 服务端 CLI 批准」,路径 B「预授权密钥免批准接入」。两台客户端机(192.168.32.3 为 node1、192.168.32.4 为 node2)分别演示。

7.1 安装 Tailscale 客户端

按 Tailscale 官方 Ubuntu 仓库流程添加密钥与源,再安装(在客户端机器执行):

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg -o /usr/share/keyrings/tailscale-archive-keyring.gpg
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list -o /etc/apt/sources.list.d/tailscale.list
cat /etc/apt/sources.list.d/tailscale.list
apt-get update && apt-get install -y tailscale
tailscale version

实测输出:

# Tailscale packages for ubuntu jammy
deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/ubuntu jammy main
Setting up tailscale (1.104.1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/tailscaled.service → /lib/systemd/system/tailscaled.service.
1.104.1
  tailscale commit: 7f4efe814ff14b064eb080344389ceb9ea2d37ac
  long version: 1.104.1-t7f4efe814-g8da26756c
  other commit: 8da26756c9a2af700dfd05fa38d21b1eef2bcaa2
  go version: go1.27.1 (tailscale/go 24ee2fd061)

客户端版本 1.104.1,满足服务端要求的 ≥ 1.80 下限。确认 tailscaled 服务运行:

systemctl start tailscaled
systemctl is-active tailscaled

实测输出:

active

7.2 服务端创建用户

注册前服务端先建一个用户(tailnet 内的资源归属单位,本文用 demo):

headscale users create demo
headscale users list

实测输出:

User created
ID | Name | Username | Email | Created
1  |      | demo     |       | 2026-10-17 21:48:51

7.3 路径 A:Web 注册 URL + CLI 批准(node1)

在 node1 上执行注册命令,指向自建控制面:

tailscale up --login-server http://192.168.32.2:8080

实测输出(命令阻塞等待批准,打印注册 URL):


To authenticate, visit:

        http://192.168.32.2:8080/register/hskey-authreq-woMfCmm7GCFT5GhopVkrNzEx

URL 末段 hskey-authreq-... 即本次注册请求的 auth-id。回到服务端,用该 auth-id 批准并归属到 demo 用户(新版 CLI 为 headscale auth register,旧命令 headscale nodes register 已标记废弃):

headscale auth register --auth-id hskey-authreq-woMfCmm7GCFT5GhopVkrNzEx --user demo

实测输出:

Node node1 registered

服务端批准后,node1 上阻塞的 tailscale up 立即返回:

Success.

在服务端确认节点已注册并在线:

headscale nodes list

实测输出:

ID | Hostname | Name  | MachineKey | NodeKey | User | Tags | IP addresses      | Ephemeral | Last seen           | Expiration | Connected | Expired
1  | node1    | node1 | [3yxWo]    | [103CQ] | demo |      | 100.64.0.1        | false     | 2026-10-17 21:50:52 | N/A        | online    | no
   |          |       |            |         |      |      | fd7a:115c:a1e0::1 |           |                     |            |           |

node1 获得 IPv4 100.64.0.1 与 IPv6 fd7a:115c:a1e0::1,状态 online。在 node1 本机确认:

tailscale ip -4
tailscale status

实测输出:

100.64.0.1
100.64.0.1  node1  demo  linux  -

7.4 路径 B:预授权密钥免批准接入(node2)

路径 A 每台节点都要人工批准,批量场景改用预授权密钥(preauthkey)。服务端生成 24 小时有效、可复用的密钥:

headscale preauthkeys create --user 1 --reusable --expiration 24h
headscale preauthkeys list

实测输出(第一条命令返回完整密钥,第二条脱敏显示):

hskey-auth-YeO_f1ecaQRq-P649QSkPdzna-EzcXUfXmjwZvcMER75HgzhcEGwxEuwn7yNs98qJFyBhwGGtnrwk
ID | Key/Prefix                  | Reusable | Ephemeral | Used  | Expiration          | Created             | Owner
1  | hskey-auth-YeO_f1ecaQRq-*** | true     | false     | false | 2026-10-18 21:51:12 | 2026-10-17 21:51:12 | demo

在 node2 上带密钥一条命令接入,无需服务端任何人工操作:

tailscale up --login-server http://192.168.32.2:8080 --authkey hskey-auth-YeO_f1ecaQRq-P649QSkPdzna-EzcXUfXmjwZvcMER75HgzhcEGwxEuwn7yNs98qJFyBhwGGtnrwk
tailscale ip -4

实测输出:

100.64.0.2

服务端确认两节点同时在线:

ID | Hostname | Name  | MachineKey | NodeKey | User | Tags | IP addresses      | Ephemeral | Last seen           | Expiration | Connected | Expired
1  | node1    | node1 | [3yxWo]    | [103CQ] | demo |      | 100.64.0.1        | false     | 2026-10-17 21:52:31 | N/A        | online    | no
   |          |       |            |         |      |      | fd7a:115c:a1e0::1 |           |                     |            |           |
2  | node2    | node2 | [I2g49]    | [OoFbg] | demo |      | 100.64.0.2        | false     | 2026-10-17 21:52:34 | N/A        | online    | no
   |          |       |            |         |      |      | fd7a:115c:a1e0::2 |           |                     |            |           |

7.5 注册结果验证:隧道互通与 MagicDNS

两节点注册完成后做端到端验证。node1 上 ping node2 的 tailnet IP 与 MagicDNS 域名(域名 = 节点名 + base_domain):

ping -c 3 100.64.0.2
ping -c 3 node2.tailnet.example.com

实测输出:

3 packets transmitted, 3 received, 0% packet loss, time 2016ms
rtt min/avg/max/mdev = 0.832/325.887/975.817/459.569 ms
--- node2.tailnet.example.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.319/0.674/0.898/0.254 ms

IP 与 MagicDNS 域名全部可达,0% 丢包。至此「服务端安装 → 客户端接入 → 双路径注册 → 端到端互通」全链路完成。注册后的日常节点管理与排障见《Headscale 运维手册》。

八、常见问题(FAQ)

Q1:tailscale up --login-server 一直卡住或报连接超时? 排查三处:服务端 systemctl is-active headscale 是否 active;server_url 与客户端访问的 IP 是否一致(本文为 http://192.168.32.2:8080);中间防火墙是否放行 8080/tcp。可用 curl -s http://192.168.32.2:8080/health 从客户端验证,期望返回 {"status":"pass"}。

Q2:headscale auth register 报 Error: missing parameters 或提示命令废弃? v0.29 起推荐 headscale auth register --auth-id <id> --user <用户>;旧命令 headscale nodes register 仍可用但已标记 deprecated。auth-id 取注册 URL 末段 hskey-authreq-...。

Q3:服务启动失败,日志报 dns.nameservers.global must be set when dns.override_local_dns is true? 这是配置校验错误:dns 段开启了 override_local_dns(默认 true)时,dns.nameservers.global 必须至少配置一个 DNS 服务器。v0.29.5 默认示例配置自带 1.1.1.1 等四个地址,若清空了 global 列表就会触发。要么补回 global 地址,要么把 override_local_dns 改为 false。该错误为致命级,服务会以 1 秒间隔循环重启(systemd 显示 activating),修复配置后 systemctl restart headscale 即恢复。

Q4:客户端注册成功但 tailscale status 显示 offline? 多为服务端刚重启、节点尚未重连,tailscaled 会自动重连(实测 20 秒内恢复 online);若长期 offline,在节点执行 tailscale status 与 systemctl restart tailscaled 后观察服务端 headscale nodes list 的 Connected 列。

Q5:配置文件改了但行为没变? Headscale 只在启动时读取配置,改动后必须 systemctl restart headscale;同时客户端侧的 DNS/策略变更由控制面异步下发,必要时在节点上 systemctl restart tailscaled 强制刷新(实测 MagicDNS 开关实验中即需如此)。配置预检可用 headscale configtest。

九、卸载与清理

方案 A(二进制安装)的完整卸载步骤,逐项执行并验证:

systemctl stop headscale
systemctl disable headscale
rm /etc/systemd/system/headscale.service
systemctl daemon-reload
rm /usr/local/bin/headscale
userdel headscale
rm -rf /etc/headscale /var/lib/headscale /var/run/headscale

实测输出(disable 时删除自启链接)与逐项验证:

Removed /etc/systemd/system/multi-user.target.wants/headscale.service.
headscale version
systemctl is-active headscale
id headscale
ls /etc/headscale

实测输出:

bash: headscale: command not found
inactive
id: 'headscale': no such user
ls: cannot access '/etc/headscale': No such file or directory

方案 B(deb 安装)的卸载更简单:

dpkg -r headscale
dpkg -l | grep headscale

dpkg -r 移除程序与服务文件,但会保留 /etc/headscale 配置与 /var/lib/headscale 数据;若确认不再使用,补 rm -rf /etc/headscale /var/lib/headscale 彻底清理。客户端侧卸载为 apt-get purge tailscale 并删除 /etc/apt/sources.list.d/tailscale.list。

⚠️ 注意:/var/lib/headscale 中的 SQLite 库与 noise_private.key 是全部节点注册数据与控制面身份,卸载即永久丢失;若只是迁移,先按《Headscale 运维手册》的备份章节导出。

十、参考链接