故障排除
常见 TSLink 问题的解决方案
认证
"未登录"错误
症状: TSLink 命令因认证错误而失败。
解决方案: 先检查 tslink status --json。默认 add/share 可以不存储凭据就入网:needs_login 是成功的授权交接,请打开其 auth_url、完成入网/审批,再轮询 tslink url <name> --wait,无需执行 tslink login。需要存储凭据的操作可使用 API 访问令牌(tskey-api-*)或 OAuth 客户端密钥(tskey-client-*):
tslink login如果你之前已经登录过,你的 API 访问令牌可能已过期。OAuth 客户端密钥不会周期性过期,但 API-token 模式当前对 Tailscale 标签/设备自动化支持最完整。使用 tslink status 查看你的认证状态。
API 密钥已过期
症状: tslink serve 在之前正常工作后出现认证错误。
解决方案: API 访问令牌会定期过期。诊断确认存储令牌已过期时,通过 tslink login 替换 管理后台 → Keys 的凭据。网关已运行时,按凭据/配置重启管理处理。这与 Tier 1 节点的浏览器入网不同。
OAuth 客户端密钥可以避免周期性 token 过期,但当前 Tailscale REST 标签/设备操作仍以 API-token 路径最完整。
钥匙串访问被拒绝
症状: TSLink 无法读写系统钥匙串中的凭证。
解决方案: 先恢复预期凭据提供方的访问:解锁它,并在提示时授予 TSLink 二进制文件访问权限。钥匙串不可达或状态不确定时拒绝写入。macOS/Linux 只有在 TSLink 证明旧钥匙串值不存在或已删除后,才允许 0600 文件回退;Windows 没有凭据文件回退。无头运行本身不能证明满足这些条件。
存储访问恢复后,stdin 可作为安全的非交互输入方式。它使用同一个存储后端,不能绕过钥匙串故障:
printf %s "$TSLINK_API_KEY" | tslink login --api-key-stdin
printf %s "$TSLINK_CLIENT_SECRET" | tslink login --client-secret-stdin受限权限文件回退和旧版 credential files 仍可能因兼容性存在,但排障说明不应指导直接写 secret 文件,因为 shell history 和 chmod 前窗口都可能泄漏凭证。
认证密钥派生失败
症状: TSLink 日志显示从 API 令牌派生认证密钥的错误。
解决方案: 认证密钥通过 Tailscale API 从 API 访问令牌动态派生。这需要:
- 有效的、未过期的 API 访问令牌。
- 到 Tailscale API(
api.tailscale.com)的网络连接。 - API 令牌必须具有足够的权限(设备写入权限)。
如果使用 OAuth 客户端密钥,tsnet 可以直接使用该密钥,但 Tailscale REST 标签/设备操作当前仍依赖 API-token 路径。
网关
网关启动失败
症状: tslink serve 立即退出或显示错误。
可能原因:
-
另一个实例已在运行。 检查
tslink status --json。默认 add/share 已会启动后台网关,请完成可能的入网授权并轮询 URL。维护需要重启时,按平台重启流程操作,不要启动第二个网关。 -
端口冲突。 如果嵌入式 tsnet 节点无法绑定监听器,检查其他 Tailscale 相关进程。
-
网络问题。 tsnet 节点需要互联网访问以连接到 Tailscale 协调服务器。验证你的网络连接。
-
无效的控制 URL。 如果使用 Headscale,检查你的控制 URL 是否正确:
bash tslink config get control-url -
节点状态错误。 检查实际错误并按节点状态恢复说明操作。网关或监督程序可能仍持有状态时,不要删除它。
服务无法访问
症状: 网关正在运行但你无法从另一台设备访问服务。
检查清单:
-
本地服务是否在运行? 对于代理服务,验证目标
host:port在本地可达:bash curl http://localhost:3000 -
访问设备是否有网络路径? 使用获准的 tailnet 成员,或已接受该应用设备分享的外部 Tailscale 账号。使用人员授权时还要检查实际登录身份与期限;Funnel 则是公开访问。
-
服务是否已注册? 使用
tslink list确认服务存在。 -
当前授权是否允许访问? 对私有 HTTP/文件应用,检查人员授权的应用范围、期限和撤销状态,或适用的旧
--allow邮箱/设备标签规则。已登记人员的授权优先于旧 allow 规则。 -
就绪与 DNS。 用
tslink url <name> --wait获取实际就绪端点,再检查接收设备的 DNS 及 tailnet 访问策略。直接向 IP 发 HTTPS 请求可能因主机名/证书验证失败,不能代替相同 URL 的测试。 -
临时节点生命周期。 短暂断连不证明设备已删除,控制面在不活跃后清理节点。考虑重启或重新入网前,先检查本地状态及远端节点状态,见临时节点未自动移除。
TCP 服务无法工作
症状: 无法连接到 TCP 服务(数据库、Redis 等)。
检查清单:
-
本地服务是否在监听? 验证 TCP 目标可达:
bash nc -zv localhost 5432 -
是否使用实际端点? 读取
tslink url mydb --wait。CLI 注册会记录目标端口;手工条目缺少port时回退到 443。对于 5432 示例,请替换为返回的主机名:bash psql -h <tslink-url-返回的主机名> -p 5432 -
客户端 Tailscale 是否在运行? 访问设备必须运行并连接 Tailscale 应用。
-
无 HTTP ACL、中间件或请求头。 TCP 转发原始字节;CLI 和 registry 验证都拒绝 TCP 非空
--allow/allowed_users。请使用 tailnet 策略及目标服务自身认证和所需 TLS,见 TCP 服务。
文件服务返回 404
症状: 文件服务正在运行但所有路径都返回 404。
解决方案: 验证 --dir 路径指向一个有效且可读的目录:
ls -la /path/to/your/directory确保目录中包含你期望提供的文件。文件服务通过 HTTPS 直接提供目录内容。
证书
TLS 证书问题
症状: 浏览器在访问服务时显示证书警告。
可能原因:
-
首次延迟。 TLS 证书在首次使用时配置,可能需要几秒钟。稍后刷新页面。
-
HTTPS 功能未启用。 确保在 Tailscale 管理控制台的 DNS 设置中为你的 tailnet 启用了 HTTPS。
-
时钟偏差。 如果你的系统时钟严重偏差,证书验证可能会失败。同步你的系统时间。
自定义域名证书错误(Roadmap / experimental)
自定义域名和 ACME 支持属于 roadmap/experimental。--domain / --acme-email 标志已移除。旧 domain / acme_email registry 键即使为空也会以 unknown_config_key 拒绝,请删除。已交付流程请使用默认 <service>.<tailnet>.ts.net 主机名。
文件和权限
权限错误
症状: TSLink 无法读取目录或写入配置路径。
解决方案:
- 确保
--dir路径存在且你的用户可读。 - 修改前先检查所选配置目录的所有权和权限。默认路径可检查:
确认实际服务用户和目录。修改运行时状态前完成确认停机,不要把通用递归所有权变更当作未经验证的修复。bash ls -ld ~/.config/tslink ~/.config/tslink/nodes
节点状态目录问题
症状: 服务启动时出现关于节点状态的错误。
解决方案: 每个服务将 tsnet 状态存储在 ~/.config/tslink/nodes/<service-name>/ 中。出现错误本身不证明状态已损坏。恢复前,保留 registry.json 中实际完整的服务条目,并检查:
tslink list --json
tslink status --json保留原 type、target/path、port、allowed_users(--allow)、tags、control_url、ephemeral、Funnel/公共确认/到期时间及其他所有设置。不要把条目替换成通用的 3000 端口代理;丢失 --allow 可能扩大访问范围。
处理节点状态前先完成确认停机;遇到错误、所有权仍不确定的警告,或仍运行/受管理的网关时停止操作。诊断保存的错误,恢复同一有效服务条目及原访问策略。明确选择完整重置时,保留配置后按配置中的受保护重置流程操作;这不是常规首选修复。随后按对应平台恢复运行、完成可能的新入网授权,并验证端点及访问限制。
注册表文件损坏
症状: TSLink 拒绝启动或显示 JSON 解析错误。
解决方案: 服务注册表(~/.config/tslink/registry.json)必须是有效的 JSON。验证它:
python3 -m json.tool ~/.config/tslink/registry.json修复前保留原文件。先完成确认停机,再修复或恢复已知有效的注册表,保留相同的完整服务条目和访问限制。通用的删除/重新添加操作会丢失这些设置。恢复受管理运行前先验证修复后的文件,见注册表配置。
守护进程
守护进程无法停止
症状: tslink stop 似乎不起作用。
解决方案:
-
检查进程是否确实在运行:
bash tslink status -
Unix 五秒超时只返回错误,不会强制退出,进程可能仍在运行;Windows 使用立即进程终止。已安装的 macOS
KeepAlive可重新拉起停止的进程。按确认停机操作,状态不确定时停止。不要删除 PID 记录来绕过所有权检查;stop 仅在确认进程不存在后清理过时记录。
自动启动不工作
症状: 运行 tslink install 后,登录时 TSLink 未自动启动。
各平台解决方案:
-
macOS: 检查 LaunchAgent 是否已加载:
bash launchctl list | grep tslink用
tslink status --json/tslink doctor --json查看监督诊断。安装的 plist 是~/Library/LaunchAgents/com.tslink.daemon.plist;需要修复时按已确认停机的重启流程操作。 -
Linux: 检查 systemd 用户服务:
bash systemctl --user status tslink如果失败,检查日志并重启:
bash journalctl --user -u tslink -n 50 systemctl --user restart tslink -
Windows: 查看已验证的 Task Scheduler/supervisor 状态:
powershell tslink status --json # Inspect data.supervision; Task Scheduler is the default, --startup is fallback.
守护进程启动时崩溃
症状: 守护进程启动但立即退出。日志可能显示关于绑定或认证的错误。
解决方案:
- 检查端口或资源冲突:
bash tslink status - 检查
tslink status --json/tslink doctor --json。Tier 1 的needs_login是入网交接,不要求存储 API 凭据;按实际模式和错误参考认证诊断。 - 用
tslink logs查看 stderr 应用/错误日志,见结构化日志。需要重启时按平台管理操作。
热重载
热重载不工作
症状: 在网关运行时添加或移除服务没有效果。
可能原因:
- 文件系统事件不支持。 某些网络挂载或虚拟化文件系统不触发 fsnotify 事件。先检查实际错误;需要重启时按平台重启流程操作。
- 注册表文件损坏。 使用 JSON 校验工具验证
~/.config/tslink/registry.json中的 JSON。
中间件更改未生效
症状: 你在 registry.json 中更新了中间件设置但没有生效。
解决方案: 可配置 middleware 尚不可用。已移除的 middleware registry 键即使为空也会以 unknown_config_key 拒绝。删除该键时保留完整服务条目及已有访问设置,见 Roadmap 配置字段。
服务类型/目标/端口更改需要重启
症状: 你在 registry.json 中更改了服务的类型、目标或端口,但更改未反映。
解决方案: 对服务 type、target 或 port 的更改需要受影响的 tsnet 节点重启。网关会自动处理此操作,但重启可能需要几秒钟,因为节点需要重新连接。
中间件(Roadmap / experimental)
Rate limiting、Basic Auth、IP allow list 和 CORS middleware 属于 roadmap/experimental,当前没有实现或 registry schema。已交付保护层是 proxy/file HTTP 服务的 --allow 加 Tailscale ACL/tag policy。
Funnel
Funnel 不工作
症状: 使用 --funnel --public 的代理服务无法从公共互联网访问。
检查清单:
- Tailscale 中已启用 Funnel。 必须在 Tailscale 管理控制台中为你的 tailnet 启用 Funnel。
- 显式公共暴露确认。 TSLink CLI 需要
--public(带不带--json都一样),它会在该服务的registry.json条目中记录public_ack: true。 - 仅代理服务。 Funnel 仅适用于代理服务,不适用于文件或 TCP 服务。
- DNS 传播。
<service>.<tailnet>.ts.net的公共 DNS 记录可能需要一些时间传播。 - 允许公开服务。 策略的
nodeAttrsFunnel 授权需允许该服务节点公开服务。它不认证访客:公网访客没有 tailnet 调用者身份检查,TSLink--allow不保护公网端点。需要的访客授权由后端应用负责,见 Tailscale Funnel。
Funnel 与中间件
症状: 中间件(速率限制、Basic Auth)不适用于 Funnel 流量。
解决方案: Configurable middleware 属于 roadmap/experimental,不是已交付的 Funnel 保护层。另请注意身份头(X-Tailscale-User-*)对于公共 Funnel 请求不可用,因为请求者不在你的 tailnet 上。
Headscale / 自定义控制服务器
无法连接到 Headscale
症状: 使用自定义控制 URL 时 TSLink 无法连接。
检查清单:
-
验证控制 URL 是否正确且可达:
bash tslink config get control-url curl https://headscale.example.com/health -
检查你的 Headscale 服务器是否正在运行且可从 TSLink 主机访问。
-
如果在
registry.json中使用按服务的控制 URL,确保每个服务的control_url正确。 -
更改控制服务器身份或处理节点状态前,保留完整服务设置,按节点状态恢复说明操作。先确认停机,不要删除 runtime 仍持有的目录。
混合控制服务器
症状: 某些服务连接到了错误的控制服务器。
解决方案: TSLink 同时支持全局和按服务的控制 URL:
- 全局:
tslink config set control-url <url>— 适用于所有没有按服务覆盖的服务。 - 按服务: 在
registry.json中的服务条目中设置control_url— 仅覆盖该服务的全局设置。
检查你的全局配置和每个服务的注册表条目,确保使用了正确的 URL。
Docker(Roadmap / experimental)
Docker 标签发现属于 roadmap/experimental。当前 TSLink 没有 Docker discovery 包或 event watcher。容器背后的服务请用 tslink add 显式注册。
指标(Roadmap / experimental endpoint)
Prometheus /metrics 属于 roadmap/experimental。TSLink 当前没有 HTTP metrics instrumentation 或 scrape endpoint。如果 curl https://<service-name>.<your-tailnet>.ts.net/metrics 失败,这是受保护 endpoint 接入前的预期状态。
管理 API(Roadmap / experimental)
Admin dashboard 和 REST API 属于 roadmap/experimental。当前 TSLink 没有 admin handler 或 dashboard;可选的 tailnet-only MCP 控制面是远程管理入口。已交付自动化请使用带 --json 的 CLI。
集群(Roadmap / experimental)
Cluster sync 属于 roadmap/experimental。当前 TSLink 没有 cluster 实现。
日志
访问日志未出现
症状: 尽管流量通过 TSLink 服务,但没有访问日志条目。
解决: 用 tslink access log --app <name> --since 24h 并检查 status/doctor 的 drops 与 missing history。访问历史说明身份、隐私与缺口;tslink logs 仍用于 daemon 诊断。
ls -la ~/.config/tslink/logs/WhoIs 解析出的 login / node 可能为空,缺少身份不证明访问日志已停止。完整字段及来源/缓存边界见结构化日志。
日志格式
症状: 需要理解或解析 TSLink 日志输出。
解决: 用 tslink access log --app <name> --since 24h 并检查 status/doctor 的 drops 与 missing history。访问历史说明身份、隐私与缺口;tslink logs 仍用于 daemon 诊断。
守护进程日志与访问日志
症状: 不确定应该检查哪个日志文件。
解决方案: 结构化网关生命周期、警告/错误及代理/文件 HTTP 访问条目共用 stderr / tslink.err.log。Daemon stdout 写入 tslink.out.log,不是结构化访问流,没有单独的 access.log。排查请求时按记录类型/服务区分;Docker events 与 cluster heartbeats 仍属 roadmap/experimental,见日志文件位置。
Tailscale API 集成
过时设备未被清理
症状: 旧的 TSLink 服务设备在移除后仍然保留在 Tailscale 管理控制台中。
解决方案: tslink remove 始终移除本地服务条目。远端 tailnet 清理是保守的:只有能证明精确所有权时,TSLink 才会删除远端设备。如果过时设备仍然存在:
- 先检查
tslink status --json及清理警告。启动时可能尝试所有权安全的清理;确需重启时按平台重启管理操作。 - 确保使用的凭证具有足够的 Tailscale API 权限(设备删除权限)。
- 如果 TSLink 报告 protected 候选或 skipped cleanup,请手动确认并从 Tailscale 管理控制台移除过时设备。
临时节点未自动移除
症状: 使用 --ephemeral 创建的服务在断开连接后仍保留在 tailnet 中。
解决方案: Tailscale 控制面在一段不活跃时间后移除临时节点,不是每次断开都移除。节点已注册/运行时,即使没有应用流量也可能仍活跃。用 tslink list --json 确认本地 ephemeral 设置,并在 Tailscale 管理控制台确认实际远端节点状态;本地标志本身不证明远端删除。不要仅因短暂断连就重启或重新注册。
远端设备清理不删除本地服务注册,注册保留至 tslink remove。详见临时节点行为及 Tailscale 生命周期契约。状态恢复或明确维护时,保留完整服务条目并遵循节点状态恢复。
获取帮助
GitHub issue tracker 已公开,可反馈不敏感的问题或更正。不要在公开 issue 中提交凭据、邀请链接、个人数据或私有 tailnet 信息。
协作者准备报告时,可附上:
- 你的操作系统和 TSLink 版本(
tslink --version) - 确切的错误消息或异常行为
- 重现问题的步骤
~/.config/tslink/logs/中的相关日志输出
分享诊断前,请移除凭据、授权 URL 及敏感本地或调用者信息。