tailscale up 参数详解:每个开关到底改变了什么
自建 headscale 之后,第一件要弄明白的事就是接入命令。tailscale up 后面那一串参数看着多,其实按用途分只有四类:接入凭据、DNS 与路由、节点身份、出口节点。本文逐条拆开讲,顺带说几个容易踩的坑。
先说清楚:tailscale up 是「声明式」的
这是理解后面所有参数的前提。
tailscale up --ssh 不是「打开 SSH 开关」,而是「把本节点的期望状态设为:SSH 开,其余一切保持默认」。下次你执行 tailscale up(不带 --ssh),SSH 就会被关掉。
也就是说,每次 up 都要把想要的参数写全,否则上一次开的选项会被重置掉。这也是为什么各类面板会帮你把完整命令实时拼出来让你复制,而不是让你手动增删参数。
如果只是想在现有配置上改一两项、不动其他的,用 tailscale set:
tailscale set --sshset 只改指定的项,其余原样保留。
接入凭据
--login-server
指向你的控制服务器。官方客户端默认连 controlplane.tailscale.com,自建 headscale 必须显式指定:
--login-server=https://headscale.example.com本地测试、没有证书的场景下写 http://192.168.6.12:8080 也可以。
--auth-key
预授权密钥,从 headscale 的「密钥管理」页签发:
--auth-key=hskey-auth-kKx9mQ2fLp3A-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx带上它就直接完成注册,不用再打开浏览器点确认,适合脚本化部署和批量装机。
几个细节:
- headscale 的密钥形状固定是
hskey-auth-<12位>-<64位>,粘贴时容易只复制一半,可以拿长度自查 - 也可以用
--auth-key=file:/etc/tailscale/authkey从文件读,避免密钥留在 shell history 里 - 签发时勾选临时节点(ephemeral),接入的节点会在下线后自动从控制台消失,适合一次性容器
- 留空则走交互式登录:命令会打印一个 URL,在浏览器里打开并确认
DNS 与路由
--accept-dns
接收控制端下发的 DNS 配置。开启后可以直接用节点名互访(MagicDNS),不必记 IP。
headscale 默认不下发 DNS 配置,所以这一项通常默认关掉 —— 控制端没配 DNS 时,开不开都一样。
--accept-routes
接收其他节点通告的子网路由。
假设 B 节点通告了它所在的 192.168.1.0/24,A 节点打开 --accept-routes 之后,才能访问那个网段里的其他机器,而不只是 B 这一台。
前提是这条路由已经在控制台批准过,否则收到通告也不会生效。
--advertise-routes
反过来,把本节点能到达的子网通告给整个网络:
--advertise-routes=192.168.1.0/24,10.0.0.0/8- 必须写网络地址加掩码。
192.168.1.0/24对,192.168.1.0不对 —— 少了掩码会被拒绝 - 多个网段用英文逗号分隔,也支持 IPv6 网段
- 通告 ≠ 生效,要去控制台把这条路由批准了,其他节点才看得到
典型的用法是把一台机器当作内网网关:它同时连着 Tailscale 网络和公司内网,把内网网段通告出去,出差在外的同事就能借道访问内网服务。
节点身份
--hostname
在控制台和 MagicDNS 里显示的节点名。留空就用系统主机名。
命名规则和 DNS 标签一致:字母、数字和连字符,不能以连字符开头或结尾,最长 63 个字符。所以 my_node、node.1 都是不合法的。
--advertise-tags
以标签身份接入,而不是用户身份:
--advertise-tags=tag:server,tag:prod好处是 ACL 可以按标签统一授权,不用一个个点名到人。
两个前提:
- 标签必须先写在控制台的策略文件里(
tagOwners),否则接入直接失败 - headscale 里标签和用户是互斥的:一个节点要么属于某个用户,要么属于一组标签,不存在两者兼有
出口节点
出口节点(exit node)是把本机的全部上网流量交给另一台机器转发 —— 相当于一个自己搭的 VPN 出口。三个参数分别对应三种角色。
--advertise-exit-node:把自己变成出口
--advertise-exit-node通告之后要去控制台批准。前提是本节点自己能正常访问外网。
--exit-node:指定走哪个出口
--exit-node=100.64.0.1填对方的 IP 或节点名,留空则不走出口。也支持 auto:any,让客户端自己挑一个延迟最低的出口节点。
--exit-node-allow-lan-access:别把内网也一起带走了
这个开关容易被忽略,但很关键。
一旦走上出口节点,默认连本地局域网也一起被送了过去 —— 打印机、NAS、路由器管理页全部失联。加上这一项:
--exit-node-allow-lan-access本地网段的流量才会走本地网卡。
安全相关
--shields-up
拒绝所有从 Tailscale 网络发起的入站连接,本节点仍然可以主动访问别人。
在咖啡厅、酒店这类不可信网络下开启更安全。代价是别人 ping 不通你,也连不进来。
--ssh
启用 Tailscale SSH:别人可以直接用节点名 SSH 连进来,不需要你分发密钥。
权限由控制台的 ACL 策略决定,不走本机的 authorized_keys —— 也就是说,改本机的 SSH 配置不会影响它。
--stateful-filtering
对经本节点转发的流量做有状态过滤:只放行已建立连接的回包,拒绝外部主动发起的连接。
注意它管的是转发流量,不管本机自己的入站。启用子网路由或出口节点时打开更安全。
--snat-subnet-routes=false
这个参数的名字和直觉相反,值得单独说。
源地址转换(SNAT)默认是开着的:流量经本节点转发给子网时,源地址会被改成本节点 IP。子网里的机器看到的是「网关过来的」,无法知道真实客户端是谁。
把这一项设成 false 意味着关闭 SNAT:
--snat-subnet-routes=false这样内网机器能看到客户端的真实 IP,便于审计和限流。但代价是必须在子网一侧补一条回程路由,把客户端所在的网段指回本节点 —— 否则回包找不到路,连接直接不通。
没把握的话,保持默认就好。
几个常见组合
普通客户端
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... --accept-dns=false内网网关(子网路由器)
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... \
--advertise-routes=192.168.1.0/24 \
--stateful-filtering出口节点
在充当出口的那台机器上:
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... \
--advertise-exit-node在要用出口的节点上:
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... \
--exit-node=100.64.0.1 --exit-node-allow-lan-access批量装机的服务器
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... \
--hostname=web-01 \
--advertise-tags=tag:server,tag:prod \
--ssh --shields-up公共网络下的笔记本
tailscale up --login-server=https://headscale.example.com \
--auth-key=hskey-auth-... \
--shields-up容易踩的坑
- 忘了 up 是声明式的 —— 少写一个参数,上一轮开的选项就被关掉了。只改单项请用
tailscale set - 通告了但没批准 —— 子网路由和出口节点都要在控制台点一下批准才生效
--advertise-routes漏掩码 —— 写192.168.1.0/24,不是192.168.1.0- 标签没在策略里声明 ——
tag:开头的标签必须先写进策略文件,否则接入失败 - 走上出口节点后内网失联 —— 加上
--exit-node-allow-lan-access - 关掉 SNAT 后忘了回程路由 —— 子网那侧的机器会连不上客户端
--auth-key只复制了一半 —— 形状是hskey-auth-<12位>-<64位>,长度能自查
速查表
| 参数 | 作用 | 默认 |
|---|---|---|
--login-server | 控制服务器地址 | 官方控制端 |
--auth-key | 预授权密钥,免交互接入 | 交互式登录 |
--accept-dns | 接收控制端下发的 DNS 配置 | 开 |
--accept-routes | 接收他人通告的子网路由 | 关 |
--advertise-routes | 把自己能到达的子网通告出去 | 关 |
--hostname | 节点在控制台和 MagicDNS 中的名字 | 系统主机名 |
--advertise-tags | 以标签身份接入 | 用户身份 |
--advertise-exit-node | 把自己变成出口节点 | 关 |
--exit-node | 走指定的出口节点 | 无 |
--exit-node-allow-lan-access | 走出口时仍直连本地局域网 | 关 |
--shields-up | 拒绝所有入站连接 | 关 |
--ssh | 启用 Tailscale SSH | 关 |
--stateful-filtering | 对转发流量做有状态过滤 | 关 |
--snat-subnet-routes | 源地址转换,写 =false 关闭 | 开 |
本文整理自 Headscale-Admin-Pro 接入命令页的参数说明。