子网路由器与出口节点:Headscale Routes配置完全指南
Headscale 是开源的 Tailscale 控制服务器自托管实现,其中 Routes(路由)功能可以让你轻松配置子网路由器(Subnet Router)与出口节点(Exit Node):把内网设备接入 tailnet,或让所有流量安全地从一个出口转发。本文将带你用最短的步骤完成配置。
两种路由角色,一个网络搞定
| 角色 | 作用 | 典型场景 |
|---|---|---|
| 🌐 子网路由器 | 连接私有云、机房内网等无法安装 Tailscale 的设备 | 远程访问家里/公司的内网服务 |
| 🚪 出口节点 | 将节点的全部互联网流量经此节点转发 | 在不可信 Wi-Fi 下安全上网、固定出口 IP |
两者的配置逻辑几乎一致,都需要双重确认(double opt-in):客户端先"宣告"能力,控制服务器再"批准"。下面分别讲解。
一键搭建子网路由器:3 步完成
第 1 步:让节点宣告子网路由
在希望充当子网路由器的机器上注册节点,并用逗号分隔列出要处理的路由网段:
sudo tailscale up --login-server <你的Headscale地址> --advertise-routes=10.0.0.0/8,192.168.0.0/24如果节点已注册,也可以用sudo tailscale set --advertise-routes=...随时更新宣告的路由。
第 2 步:在控制服务器批准路由
用headscale nodes list-routes查看当前可用的路由(命令实现见 cmd/headscale/cli/nodes.go):
$ headscale nodes list-routes ID | Hostname | Approved | Available | Serving (Primary) 1 | myrouter | | 10.0.0.0/8 | | | | 192.168.0.0/24 |可以看到路由"可用"但尚未批准。执行批准命令:
$ headscale nodes approve-routes --identifier 1 --routes 10.0.0.0/8,192.168.0.0/24 Node updated再次运行list-routes,路由会出现在Approved列中,子网路由器即刻生效 ✅
第 3 步:其他节点接受路由
在需要访问内网的客户端上执行:
sudo tailscale set --accept-routes至此,tailnet 内的其他设备就可以通过子网路由器访问 10.0.0.0/8 和 192.168.0.0/24 中的设备了。
出口节点配置:比子网路由器更简单
出口节点的配置流程与子网路由器高度一致,只是宣告的是特殊路由0.0.0.0/0(IPv4)和::/0(IPv6):
1️⃣ 节点上宣告出口能力:
sudo tailscale up --login-server <你的Headscale地址> --advertise-exit-node2️⃣ 控制服务器批准(只需批准 IPv4 或 IPv6 其中一条,另一条会自动批准):
$ headscale nodes list-routes 1 | myexit | | 0.0.0.0/0 | $ headscale nodes approve-routes --identifier 1 --routes 0.0.0.0/03️⃣ 客户端指定出口节点:
sudo tailscale set --exit-node myexit从这一刻起,该节点的所有互联网流量都会经由myexit转发 🚀
进阶技巧:用策略自动批准路由
每次新增路由都要手动批准?Headscale 的策略文件(Policy)支持autoApprovers,可以实现路由宣告后自动批准。
自动批准子网路由:给路由节点打上tag:router标签,策略中声明该标签拥有自动批准权:
{ "tagOwners": { "tag:router": ["alice@"] }, "autoApprovers": { "routes": { "192.168.0.0/24": ["tag:router"] } }, "grants": [ { "src": ["autogroup:member"], "dst": ["autogroup:member"], "ip": ["*"] } ] }节点加入时带上标签:--advertise-tags tag:router --advertise-routes 192.168.0.0/24,路由即刻自动生效。
自动批准出口节点:写法类似,只需在autoApprovers中写"exitNode": ["tag:exit"]。
完整策略语法可参考 docs/ref/policy.md。
用策略限制路由的使用者
默认情况下所有节点都能使用已批准的路由和出口节点。想精细管控时,在策略中使用autogroup:internet即可限制"谁可以使用出口节点";甚至可以用via字段为不同用户指定专属出口节点:
{ "grants": [ { "src": ["alice@"], "dst": ["autogroup:internet"], "via": ["tag:exit1"], "ip": ["*"] } ] }这样 alice 只能经由tag:exit1标记的出口节点上网,其他出口节点对她不可见。
常见问题排查 🛠
- 路由不生效:首先确认路由器节点是否开启了IP 转发(IP forwarding)——子网路由器和出口节点都要转发流量,这是最常见的坑。
- 路由不在列表中:检查节点是否在线,以及
--advertise-routes参数是否拼写正确(多个网段用逗号分隔,不要加空格)。 - 客户端看不到路由:确认客户端执行过
tailscale set --accept-routes,且策略允许其访问目标。 - 想要高可用:Headscale 默认支持多路由冗余——当至少两个节点宣告同一前缀时自动启用 HA,任一节点下线时流量自动切换到另一个(配置项为
node.routes.ha,见 docs/ref/configuration.md)。
总结
| 操作 | 客户端命令 | 服务器命令 |
|---|---|---|
| 宣告子网 | up --advertise-routes | nodes approve-routes |
| 宣告出口 | up --advertise-exit-node | nodes approve-routes |
| 接受/使用 | set --accept-routes/set --exit-node | — |
更多细节请阅读官方路由文档 docs/ref/routes.md。掌握子网路由器与出口节点后,你的 Headscale tailnet 就能无缝覆盖内网设备,并随时拥有一把安全的"互联网钥匙" 🔑
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考