Blog

Headscale:自建 Tailscale 控制面

节点一多,手写 WireGuard 的对端矩阵会指数膨胀。Tailscale 体验极佳;想把控制面握在自己手里时,我选了 Headscale。这篇不写安装点击录,只写 访问控制列表是怎么一步步想清楚的——因为真正卡人的不是服务启动成功,而是策略写错把自己锁在咖啡店里,手机还连不上管理口。

先问:我要隔离的是什么

默念一遍资产清单:

  • 网络附加存储的管理口(网页与安全壳)
  • 虚拟化平台与路由器管理
  • 游戏服端口(朋友需要,但不需要管基础设施)
  • 笔记本、手机等出行节点
  • 自动化用户(备份、监控抓取)

「一个大二层虚拟专用网,谁连上谁都能扫全网」是我明确不要的。目标更接近:身份加标签决定可达性,而不是「进了隧道就进了家」。零信任在家庭实验室里不必喊得很响,但策略里要敢写「访客永远碰不到存储管理口」。

第一阶段:全通,只为证明控制面活着

上线后前两周访问控制几乎放行。原因很务实:同时排障中继是否通、名称解析是否正常、某款安卓是否注册成功,又同时排障「策略是否过严」,会把问题缠在一起,最后谁也说不清。

这阶段清单只有三条:节点能注册、能互通;控制面数据库有备份任务;带外通路仍然可用——物理机控制台、云厂商远程桌面,或一条不经过 Headscale 的应急隧道。

没有带外,就不要收紧策略。这句话我写进了自己的运维手册第一行。收紧是特权操作,必须假定你会写错。

第二阶段:标签比用户名好用

起初按「用户」写规则,很快发现:同一用户既有受信笔记本,也有临时实验机;朋友账号只该碰游戏服。改为按标签思考:

  • 管理设备标签:我的日常终端
  • 基础设施标签:存储、虚拟化、网关
  • 游戏标签:帕鲁、异星工厂等
  • 访客标签:好友设备
  • 自动化标签:备份与监控

在策略里让访客标签只能访问游戏标签的指定端口,比「张三能访问整个内网段」清晰得多。给节点打标签时顺手写进文档:新机器默认不可信标签,直到人工升级。标签是策略的词汇表,词汇表乱了,规则再长也只是错得更复杂。

第三阶段:收紧时的三次差点锁死

第一次: 管理口只放行管理设备标签,但手机客户端还没打上标签,人在外面改完策略后只能干瞪眼。靠带外远程桌面救回。此后任何收紧前,先确认自己当前出口设备已正确打标。

第二次: 把域名解析也强依赖进网格,结果断网时解析失败,连控制面域名都解不开。后来控制面域名保留公网解析,或在应急机器上写死地址。

第三次: 自动化备份机标签写错,夜里备份全失败,早上看监控才发现「不是盘坏了,是策略」。策略变更后要抽测三条路径:人工远程登录一条、备份任务一条、好友进游戏服一条。

渐进口诀:先通、后标、再收,每次只拧一格,保留回滚用的旧策略文本。 不要在同一天既换中继又换全站拒绝规则。

控制面本身也是生产

# 升级前:停服或至少快照数据库(路径按你的部署)
cp -a /var/lib/headscale/db.sqlite /backup/headscale-db-$(date +%F).sqlite

丢控制面数据库等于丢身份图:节点要重新信任,策略要重来。长期不用的节点从控制面删掉;邀请链接设过期。客户端版本尽量统一,减少「半截连上」的幽灵问题。盯控制面进程与磁盘,别让日志把盘写满——控制面挂了,网格再漂亮也只是一堆到不了的对端。

和手写 WireGuard 怎么选

条件 更倾向
节点少、拓扑固定、你想完全透明 手写隧道
节点多、跨地址转换、要按人或标签策略 Headscale 或官方协调
完全不想维护控制面 官方托管控制面

网格让我在咖啡店打开笔记本像坐在家里——前提是控制面还活着,且每一次收紧都留了退路。零信任不是贴在拓扑图上的标签,是你改策略时手是否发抖、发抖之后有没有第二条路回家。

若你正从手写隧道迁过来:可以并行跑一段时间,先把节点注册与标签体系跑顺,再迁移访问路径,最后才拆掉旧隧道。迁移期的「双通路」本身就是最好的带外保险,比写完完美策略再一次性切换更不容易把自己锁死。

← Back to Blog