远程访问与 HTTPS
这一页涉及两件相互独立的事,先分清再往下读:
- 远程访问:让别的设备连上你这台机器的 AI Switch 管理界面(Web 服务,默认端口
3090)。 - 本地算力池 HTTPS:让本机的路由代理(默认端口
19527)以https://提供服务,给那些只接受 HTTPS 上游地址的客户端使用。
两者用的是不同的端口、不同的证书体系,不要混在一起。
远程访问的两条路
| 方式 | 可见范围 | 传输加密 | 适用场景 |
|---|---|---|---|
| Tailscale 私网 | 仅你自己 Tailscale 账号下的设备 | 由 Tailscale 提供 | 手机、笔记本访问家里那台常开的机器 |
| Tailscale Funnel | 公网任何人可访问该地址 | Tailscale 提供的 HTTPS | 确有必要对外提供访问时 |
两种方式都不改变 AI Switch 自身的鉴权:访问令牌照样要带。Tailscale 只解决"链路能不能通、通道是否加密",不代替应用层的授权。
跨端连接建议把公网 HTTPS作为默认入口:H5 需要 CORS,小程序需要把域名加入合法请求域名。私网入口只给原生 App 使用。
Tailscale 私网
AI Switch 内置了一个 Go 编写的 sidecar(ai-switch-tsnet,基于 Tailscale 的 tsnet 库),它在桌面应用进程之外以用户态方式加入你的 tailnet。桌面端不需要安装系统 Tailscale 客户端;手机 App 仍需安装官方 Tailscale App,并登录同一个 tailnet。uni-app 本身不集成 Tailscale SDK。
启用步骤
- 在桌面端设置 → Web 服务里勾选启用安全网络。
- 访问模式选择仅私网。
- 保存并启动服务。
- 在安全网络区域点击使用 OAuth 登录,浏览器会打开 Tailscale 授权页面,完成授权后回到应用。
登录成功后界面会给出可用的访问地址。私网只发布带 MagicDNS 名称的 HTTPS 地址,形如:
https://ai-switch.<your-tailnet>.ts.net:3090不要把 100.x.y.z 直接填入移动端:Tailscale HTTPS 证书按 MagicDNS 主机名签发,使用 IP 会导致证书主机名校验失败。请先在 Tailscale 管理后台启用 MagicDNS 和 HTTPS certificates。sidecar 默认使用主机名 ai-switch,状态数据保存在 ~/.ai-switch/tailscale/。
另一种登录方式:授权密钥
如果不方便走浏览器 OAuth(比如远程 SSH 到一台没有图形界面的机器上),可以在同一个区域填入 Tailscale 授权密钥并点击使用授权密钥连接。密钥会被持久化到 ~/.ai-switch/tailscale/auth-key,以便重启后自动重连。
授权密钥以明文保存
~/.ai-switch/tailscale/auth-key 是明文文件。用完后如果不需要自动重连,建议在 Tailscale 后台吊销该密钥,或改用 OAuth 登录。
登录不是自动发生的
这一点值得强调:应用启动时不会自动登录 Tailscale。
启动时的恢复逻辑只在满足下列条件之一时才会尝试重连:本地存在已保存的授权密钥、或 sidecar 目录里存在此前持久化的 tsnet 登录状态。都不满足时,界面会显示"安全网络正在等待登录",等你手动点登录。
也就是说,装上应用不等于加入了某个网络,你必须显式做一次授权动作。
手机扫码配对
在桌面端安全网络区域点击显示移动端配对二维码,再在移动端添加或编辑真实实例时点击扫码导入。二维码只包含远程 URL、短期一次性配对码和过期时间,不包含 Web Service 长期访问令牌;配对码兑换成功后,服务端返回独立的移动端令牌。
扫码只是回填地址和配对码,移动端仍然允许手动修改公网/私网 URL、手动输入或替换 Token。配对码只能使用一次,过期后需要重新生成。App 使用私网 URL 前必须已经在官方 Tailscale App 中登录同一 tailnet;H5 和小程序应选择公网 HTTPS URL。
Tailscale Funnel(公网)
把访问模式改成公网访问后,sidecar 会用 Tailscale Funnel 监听,服务地址变成一个公网可达的 HTTPS 地址:
https://ai-switch.<your-tailnet>.ts.netFunnel 模式默认走 443 端口(443 / 8443 / 10000 这几个 Funnel 支持的端口会被保留使用)。要注意:
- 你的 Tailscale 账号必须允许 Funnel。 这是 tailnet 的策略设置,在 Tailscale 后台开启。
- HTTPS 由 Tailscale 提供,证书由 Tailscale 签发和续期,你不需要自己准备证书。
- 访问令牌仍然生效。 任何人都能连到这个地址,但没有令牌拿不到任何数据——令牌是这时唯一的门。
- 界面上的登录动作照旧。 切到公网模式不会跳过 Tailscale 登录。
自备证书暴露 Web 服务
如果你不用 Tailscale,而是想直接把 Web 服务绑到一个非环回地址上,那就必须自己提供 TLS 证书,否则服务拒绝启动(错误码 web.sensitive_transport_requires_tls)。
- 桌面端:编辑
~/.ai-switch/web-service.json,填写tlsEnabled、tlsCertPath、tlsKeyPath(界面上没有这三项的输入控件),然后重启 Web 服务。 - 独立服务器:设置环境变量
AI_SWITCH_TLS_CERT_PATH与AI_SWITCH_TLS_KEY_PATH。
两个路径必须同时提供,只给一个会以 web.tls_paths_incomplete 报错。详见 Web 服务模式 和 独立服务器。
本地算力池 HTTPS
这部分和远程访问无关,解决的是另一个问题:某些客户端只接受 https:// 的上游地址,而 AI Switch 的本地路由代理默认是 http://127.0.0.1:19527。为此应用可以生成一套自签证书,让本地代理额外以 HTTPS 提供服务。
HTTPS 不会取代 HTTP,而是独占自己的端口:HTTP 继续在原端口服务,HTTPS 从「HTTP 端口 + 1」起绑定,常态即 http://127.0.0.1:19527 与 https://127.0.0.1:19528。写入客户端配置的一直是 HTTP 地址,因为自带 CA bundle 的客户端(macOS/Linux 的 curl、Node 版 CLI)读不到装进系统信任库的根证书,把它们指向 https:// 只会换来证书校验失败。所以:正常情况用 HTTP 端点即可,HTTPS 端点留给确实要求 TLS 的客户端手动填写。 两个地址都能在「写入配置」弹窗和 HTTPS 面板里看到。
默认是关闭的
route-proxy-https.json 的默认值是 enabled: false、autoStart: false。也就是说:除非你主动去开,本地 HTTPS 不会启用,证书也不会生成。安装应用不会往你的系统信任库里写任何东西。
代理本身始终只绑定 127.0.0.1,端口从 19527 起,被占用时向上寻找下一个可用端口。启用 HTTPS 不会让它监听外部地址;HTTPS 那个监听器同样只在回环上,并且它起不来时只记录原因,HTTP 继续服务。
证书存在哪里
启用后,证书材料生成在 ~/.ai-switch/certs/route-proxy/:
| 文件 | 内容 |
|---|---|
root-ca.pem | 自签根证书,需要导入系统信任库的就是这个文件 |
root-ca-key.pem | 根证书私钥(Unix 下权限 0600) |
server-cert.pem | 代理实际使用的服务器证书 |
server-key.pem | 服务器私钥(Unix 下权限 0600) |
metadata.json | 根证书 SHA-256 指纹、SHA-1 指纹、有效期等元信息 |
证书参数:根证书 CN 为 AI Switch Route Proxy Root CA,有效期 3650 天;服务器证书 CN 为 AI Switch Route Proxy localhost,有效期 823 天,SAN 只包含 localhost 和 127.0.0.1。两张证书都倒签 1 天以容忍客户端时钟偏慢,所以服务器证书实际跨度为 824 天 —— 刻意留在 825 天以下,因为 macOS 和 iOS 对 TLS 服务器证书强制这一上限,自建根签发的证书同样受限。因为 SAN 里没有任何外部主机名,这套证书只对本机访问有效,拿去给别的机器用是不成立的。
怎么信任
在桌面端的 本地算力池 HTTPS 面板里操作,可用动作有:
- 生成并导入根证书:一步完成生成证书材料 + 写入系统信任库。
- 重新导入根证书:证书还在但信任状态丢了(比如系统信任库被清理过)时用。
- 重新生成证书:吊销旧材料、生成新的一套。生成过程使用临时目录加原子替换,失败时回滚到
.backup,不会留下半成品。 - 卸载根证书:从系统信任库移除,但保留文件。
- 删除本地证书材料:彻底删除文件,前提是 HTTPS 已关闭且根证书已卸载。
- 打开证书目录:在文件管理器里打开上面那个目录(桌面独占)。
面板同时显示根证书指纹、到期时间、证书目录和当前信任状态(已被系统信任 / 已被 NSS 信任 / 部分信任 / 未信任 / 未知)。
如果自动导入失败(常见于权限不足或非标准发行版),面板会给出手动信任步骤。实际使用的命令按平台不同:
certutil.exe -user -addstore Root "$HOME\.ai-switch\certs\route-proxy\root-ca.pem"写入的是当前用户的信任库(-user),不需要管理员权限。
macOS 写入登录钥匙串:
security add-trusted-cert -r trustRoot -k ~/Library/Keychains/login.keychain-db \
~/.ai-switch/certs/route-proxy/root-ca.pem不带 -d 写入的是用户信任域,因此不需要管理员权限 —— 但 macOS 修改信任设置前仍会要求输入密码。取消那个弹窗会导致证书被导入却未被信任,浏览器随后报 ERR_CERT_AUTHORITY_INVALID。AI Switch 会把这种状态判为未信任,所以如果导入成功后信任状态仍显示未信任,请重新执行并完成弹窗验证。撤销时记得加 -t —— security delete-certificate -Z <sha1> -t ~/Library/Keychains/login.keychain-db —— 否则信任设置会比证书活得更久。
Linux 因发行版而异,按你的系统选一条:
# p11-kit(Arch、Fedora 等)
trust anchor ~/.ai-switch/certs/route-proxy/root-ca.pem
# Debian / Ubuntu
sudo install -Dm644 ~/.ai-switch/certs/route-proxy/root-ca.pem \
/usr/local/share/ca-certificates/ai-switch-route-proxy-root-ca.crt
sudo update-ca-certificates
# RHEL / CentOS / Fedora
sudo install -Dm644 ~/.ai-switch/certs/route-proxy/root-ca.pem \
/etc/pki/ca-trust/source/anchors/ai-switch-route-proxy-root-ca.pem
sudo update-ca-trust extractFirefox 和部分基于 NSS 的应用不读系统信任库,需要单独导入:
certutil -A -d <nss-db-path> -n "AI Switch Route Proxy Root CA" -t C,, \
-i ~/.ai-switch/certs/route-proxy/root-ca.pemNSS 库里的昵称必须与根证书 CN 一致,也就是 AI Switch Route Proxy Root CA,卸载时按这个名字查找。
面板给出的手动步骤里路径是根据你机器上的实际位置生成的,直接照抄面板上的命令比照抄本页更可靠。
手工验证 HTTPS 端点
想确认 HTTPS 端点通不通,直接拿系统 curl 打就行——注意 Windows 上要加 --ssl-no-revoke:
curl.exe --ssl-no-revoke --cacert "$HOME\.ai-switch\certs\route-proxy\root-ca.pem" `
-H "Authorization: Bearer <代理 key>" https://127.0.0.1:19528/v1/modelsWindows 的 curl 走 Schannel,会去查根证书的吊销状态;自签根证书没有 CRL/OCSP 分发点,不加这个开关会得到 curl: (60) schannel: the revocation status is unknown,看起来像证书无效,其实只是查不到吊销信息。加上之后返回 200,与打 HTTP 端点的结果一致。
同一时刻打 HTTP 端点(http://127.0.0.1:19527/v1/models)应当同样返回 200 且不需要任何证书参数——这正是两个端口并存要保证的事。反过来,用明文 HTTP 去打 HTTPS 那个端口会得到 curl: (1) Received HTTP/0.9 when not allowed,因为那个监听器只说 TLS。
私钥不会外泄到界面
代理 HTTPS 的状态接口只返回证书目录、根证书路径、信任状态、到期时间和手动步骤,不返回任何私钥内容。
安全注意事项
远程访问的几条底线
- 所有
/api/*与/ws/events请求都需要访问令牌,走 Tailscale 也一样。 Tailscale 不是鉴权层,它只负责链路。 - Tailscale 登录是手动动作。 应用启动不会自动登录;只有在本地存有授权密钥或此前的 tsnet 状态时才会尝试重连。
- 绑
0.0.0.0之前先想清楚。 非环回监听必须配 TLS(否则拒绝启动),并且意味着这台机器所在网络里的任何设备都能碰到这个端口。 - 启用 Funnel 之前更要想清楚。 那是一个公网地址,令牌是唯一的门。除非确有必要,优先用私网模式。
- 令牌等价于 shell 权限。 Web API 包含终端会话命令,令牌泄露的后果不止于配置被读取。
- 自签根证书只为本机服务。 它的 SAN 只有
localhost与127.0.0.1;不要把根证书私钥拷到别的机器,也不要用它去为远程访问签发证书。 - 移动端令牌的存储按平台降级。 App 可注入 iOS Keychain / Android Keystore 适配器;H5 和小程序没有这些原生能力时使用
uni本地存储以保持兼容。无论使用哪种存储,都不要把令牌放进二维码或日志。 - 不再需要时记得清理。 关闭本地 HTTPS 后,用面板的卸载与删除动作把根证书从系统信任库里移除,别让一个不再使用的根证书长期留在信任库中。