Portal Gateway:一次设备共享
主动启用 portal 设备共享,为选定的本机和远程应用提供入口,每次请求检查 people 授权。
要让 tailnet 之外的人访问一个或多个私有应用,可启用 TSLink gateway 模式、添加应用路由,再向其实际 Tailscale 登录账户授予有期限的权限。对方必须安装 Tailscale、登录并接受一次 portal 节点设备共享;后续路由应用的授权变更无需再次邀请。网络策略必须允许连接。Gateway 模式需主动启用;默认仍逐应用分享。
同一批人需要多个私有 HTTP 或文件应用,且应用集合会变化时,可以使用 gateway。需要独立主机名和 cookie 时,保留默认逐应用分享。Gateway 路由共用一个主机名,每个应用使用独立 HTTPS 端口,并保留应用根路径。端口对应不同浏览器 origin,但不隔离 cookie:应用可能使用冲突的 cookie 名称,或设置影响其他端口的 cookie。目前没有 cookie 命名空间。TCP、公共 Funnel 和浏览器访客链接应用不能作为 gateway 路由。
启用并路由本机应用
tslink portal enable --owner you@example.com --gateway
tslink portal route add photos
tslink add notes --proxy localhost:3000 --portal-only
tslink add files --dir /srv/shared --portal-only --portal-port 8445
tslink portal route list --json
tslink status --urlsphotos 必须已是私有 HTTP/文件应用;添加路由会保留其独立节点。新的 --portal-only 应用没有应用节点。私有主页监听 443,每个路由应用使用独立 HTTPS 端口,默认从 8443-8499 分配。使用 status 或 tslink url notes --wait 返回的准确 URL,例如 https://home.example.ts.net:8443/,不要猜主机名或端口。新启用的节点可能需完成入网才能就绪。
tslink portal route add photos --port 8447重新添加时省略 --port 会保留已分配端口。tslink portal route remove photos 只删除该路由。Portal-only 应用必须保留路由;如需移除应用,改用 tslink remove notes。用 tslink portal enable --owner you@example.com --gateway --gateway-ports 9000-9099 选择端口范围,现有路由端口必须仍在范围内。
不带 gateway 选项的 enable 会保留现有 gateway。单独 --gateway 保留范围和标签;范围/标签选项必须搭配 --gateway。移除全部路由后,用 tslink portal enable --owner you@example.com --gateway=false 显式关闭 gateway 模式。tslink portal disable 关闭主页和全部路由,但保留配置和入网状态。Portal 拒绝公共 Funnel。
向一个人分享 gateway
tslink people add alice@example.com --apps photos,notes,files --for 7d --invite --print-links --qr
tslink people update alice@example.com --apps notes,files --for 7d
tslink people update alice@example.com --invite创建邀请需要已存储的用户拥有的 Tailscale API token;OAuth client token 不能创建设备邀请。请自行发送生成的消息。--print-links 会显示 bearer 链接,需妥善保密。对于路由应用,TSLink 每人记录一个 gateway 设备邀请;后续路由应用授权变更无需新邀请。所选非路由应用仍需各自共享,并产生警告。应用直连 URL 保留独立设备共享和访问检查。普通二维码/手机指南指向 gateway 主页;邀请二维码使用 --qr-invite @gateway,搭配 --invite --print-links 及 --qr 或 --qr-png。
即使未启用 gateway,list、status、add 也会为 people-scoped 应用报告 allow.mode: people。撤销阻止后续请求;已接受的流可能继续。移除人员时先保存本地拒绝,再尝试撤销待接受的 gateway 邀请。已接受的设备共享可能保留,但无法绕过本地拒绝。通过设备共享接入的外部访客不会获得仅 tailnet 成员可用的访问申请表单。
路由其他主机上的应用
tslink portal enable --owner you@example.com --gateway --gateway-tag tag:gateway
tslink add media --remote https://mini.example.ts.net:9443 --portal-port 8446--remote https://<node>.<tailnet>.ts.net 创建 portal-only HTTPS 代理。LocalAPI 必须实际报告 gateway 已带标签,只有配置值不够。--gateway-tag 需要凭据;零凭据 gateway 支持本机应用。远程应用必须在自身策略中允许 gateway 标签(TSLink 应用需显式 tag allow list)。注册不会编辑远端 ACL 或注册信息。
远程目标必须是 gateway 实际观察到的 tailnet 后缀内的 peer MagicDNS 名称,默认端口为 443。HTTP、IP 字面值、URL 凭据、fragment 和外部后缀一律拒绝;不支持 .ts.net 之外的自定义控制服务器域名。在路由激活、新建上游连接和健康探针时检查 peer 身份;每次请求重新检查标签和 tailnet 后缀。请求和探针通过 gateway 自身 netstack 连接 peer 的 Tailscale IP,不经宿主网络或解析器,TLS 仍验证注册主机名。
远端主机认证 gateway 节点本身。远程应用不会收到访客身份 header 或转发的访客 IP;需要区分具体人的应用必须保留自身登录。本机上游接收经过验证的访客 Tailscale 身份 header。这是显式注册远程目标,不是多主机发现或汇总清单。
连接与请求检查
每个连接都需在五秒内成功完成 WhoIs,之后才进行 TLS。获准使用任一路由应用的调用者可在另一条路由完成 TLS,但 HTTP gate 会拒绝其无权使用的应用。陌生人及仅获授非路由应用的人,在路由端口收不到 TLS 字节。每次 HTTP 请求和 WebSocket upgrade 都重新执行 WhoIs、registry 验证及 people 决策;registry 失败时拒绝访问。Tailscale 网络策略和后端认证仍适用。
浏览器 fetch、表单和 WebSocket upgrade 默认必须同源,包括 HTTPS scheme、主机名和端口。允许顶层 GET/HEAD 导航;没有 Origin/fetch metadata 的非浏览器请求仍需通过身份检查。tslink portal route add photos --allow-cross-origin 会主动减弱浏览器请求边界;同属 tailnet 不是启用理由。端口不提供 cookie 隔离。
健康与访问证据
Portal-only 代理/文件应用无需访客流量也会定期检查。远程检查使用相同的 tagged tsnet 传输。未配置 HTTP 状态范围时接受 200-399,不跟随重定向;401/403 需显式范围。意外响应保持 degraded,不触发 app_down 或“离线起始时间”;只有不可达后端在连续三次失败后成为 down。观察超过两倍间隔加超时后为 unknown。后端健康不能证明访客可达性。请使用健康设置和 tslink health set notes --path /health,避免用 add 替换整个应用。
status 和 doctor 的 portal.gateway 报告观察到的持久性、标签、NodeID、所有权证据、范围、路由状态和本次运行的 dropped 连接计数。连接丢弃日志按 gate 限频;主页使用 @portal 标记。计数包含因限频省略的丢弃。请求事件保留应用名,增加 via: portal 和稳定 reason。
| Reason | 含义 |
|---|---|
remote_upstream_requires_tag | 未观察到 gateway 实际带标签 |
remote_upstream_outside_tailnet | 远程主机不在观察到的后缀内 |
remote_upstream_not_peer | 注册主机不在 gateway 的 peer map 中 |
upstream_down | 上游失败,包括复用连接时远程信任检查失败 |
client_canceled | 代理期间、响应 header 前客户端离开;allowed,状态码 499 |
route_closed / node_closed | TSLink 拆除路由/节点时中断请求;allowed,header 前为 503,之后保留已转发状态码 |
识别身份期间取消不产生事件。响应 header 后取消保留已转发状态码。真实后端故障增加 error_class:connection_refused、connection_reset、tls、timeout 或 other。保留范围、丢弃和崩溃缺口见访问历史。
恢复 stale 邀请
Gateway 在凭据和交互入网路径上均持久化。路由、授权、owner/admin 和端口范围编辑保留共享节点。启用/禁用、主机名/标签编辑,或 daemon 重启时的凭据模式/control URL 变化可能替换节点。NodeID 变化产生 gateway_node_identity_changed;旧节点的已接受共享不能转移。
先用 tslink doctor --json 和 tslink status --json 证明新 gateway 已运行、持久化且有所有权证据。比较 tslink people list --json 中活跃邀请的 node_id 与 portal.gateway.node_id。Stale 活跃尝试使 people update --invite 返回 complete: false 和 gateway_invite_stale。
tslink people update alice@example.com --invite --replace-invite @gateway=12345将 12345 替换为记录的旧 ID。该操作把 stale 本地尝试(包括已接受共享)退役为 target_gone,允许为当前 gateway 创建邀请,但不会撤销旧远程共享。没有记录 ID 的 stale pending/sending/unknown 尝试需显式执行 tslink people update alice@example.com --invite --reconcile-invite @gateway=none;以后重试用普通 --invite。接收者必须接受新设备邀请。身份变化警告作为历史保留;已恢复的 target_gone 记录无需再次替换。不要跨节点复制入网 marker。完整流程见 TSLink v0.2.0 人员指南。
Registry schema 与降级
Gateway 配置使用 registry schema 3。现有 registry 在使用 gateway 配置前保留原版本;旧 reader 拒绝 schema 3。降级前:
- 停止新 daemon,备份 registry 和 portal 状态。托管服务按验证停止操作。
- 使用 v0.2.0,明确移除或替换 portal-only 和 remote 应用,移除全部路由,再关闭 gateway 模式。
- 记录过的 gateway 邀请即使在 gateway 关闭后也让 schema 保持 3。若仍存在记录,恢复启用 gateway 前的 registry 备份;此后的 people 和邀请变更将丢失。
- 启动旧 daemon 前确认 guest 网络共享及授权预期。只替换二进制不构成降级。
完整传输、持久性、浏览器及 MCP 边界见 TSLink v0.2.0 portal.md。