Tauri 2 内网 OTA 静默失败:不是必须 HTTPS,是你少了一个 flag
把桌面 APP 部署到无公网 TLS 证书的私有服务器时,Tauri 2 的自动更新器会在运行时静默报一个网络错误——URL 用浏览器直接访问完全正常,但 updater 就是拿不到 manifest。工程师通常会得出一个错误结论:"Tauri updater 必须 HTTPS,内网没法做 OTA",然后放弃,让用户手动重装。
这个结论是错的。
现象
内网私有部署场景:updater endpoint 是 http://192.168.x.x/update/update.json,浏览器访问返回正确的 JSON。但 APP 启动时 updater 回调的 error 是 network error 或 TLS handshake 相关报错(对着 80 端口尝试握手 443)。
构建日志也可能出现另一个迹象:.app.tar.gz.sig 文件根本没有生成——意味着签名密钥没有正确注入,updater 连签名都验不了,更谈不上拉包。
根因
Tauri 2 updater 插件默认拒绝 http:// scheme,会在发起请求前做协议校验,非 HTTPS 直接以 network error 返回,不走网络层。这和浏览器的混合内容策略类似,但报错信息不够明确,很容易被误判为服务器问题。
大多数教程和 v1 时代的文档都在强调「updater 需要 HTTPS 端点」,没有提到 v2 已经有官方 escape hatch。于是团队要么放弃 OTA,要么走弯路:
- 放弃 OTA,用户每次升级手动重下安装包。
- 给内网服务器签自签名证书 + 在每台员工机器上安装根 CA,折腾 Keychain / MDM / 杀毒软件信任——代价极高,而且对安全性毫无贡献,因为 updater 真正的安全锚点是
.sig签名,不是 TLS。 - 在构建脚本里把
http:强制替换成https:,让 updater 对一个根本不存在的 443 端口静默失败——"内网 OTA 设计上不可用"写进了 ADR,未来的工程师继续踩同一个坑。
ed25519 minisign 签名验证是 updater 的真正安全锚点。攻击者即使在明文 HTTP 路径上篡改 .app.tar.gz,签名校验失败后 updater 拒绝安装。TLS 是额外防护层,不是必要条件。为了让 updater 能走 HTTP 而给所有员工机器推自签 CA,是用运维成本换了零安全收益。
正解
Tauri 2 提供了官方标志 dangerousInsecureTransportProtocol,专门用于内网/私有云/离线部署场景。三个字段必须同时存在:
{
"bundle": {
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
"endpoints": ["http://192.168.x.x/update/update.json"],
"dangerousInsecureTransportProtocol": true,
"pubkey": "<minisign 公钥完整内容,含头部注释,单行>"
}
}
}createUpdaterArtifacts: true— 缺少此项,构建不会产出.app.tar.gz和.sig,updater 无文件可拉。dangerousInsecureTransportProtocol: true— 官方 v2 标志,白名单http://scheme,不是社区 hack。pubkey—~/.tauri/<app>-updater.key.pub的完整内容(含头部注释行),这是签名验证的锚点,不可省略。
capability 文件里也要加权限,否则 updater 调用被 ACL 拦截:
{
"permissions": ["updater:default"]
}构建时通过环境变量注入私钥(内容,不是路径):
export TAURI_SIGNING_PRIVATE_KEY="$(cat ~/.tauri/myapp-updater.key)"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""构建完验证签名是否生成:
ls src-tauri/target/release/bundle/macos/
# 必须看到 YourApp.app.tar.gz.sig,没有说明私钥没注入成功flag 的名字里有 dangerous 是因为它放开了传输层加密,但签名校验始终开启——这是设计有意为之。没有 dangerousNoSignatureVerification 这种 flag,签名层无法绕过。
踩坑快速对照
| 症状 | 真实原因 |
|------|----------|
| updater 报 network error,浏览器访问 URL 正常 | 缺 dangerousInsecureTransportProtocol: true |
| 构建产物没有 .sig 文件 | createUpdaterArtifacts: false 或私钥环境变量为空 |
| updater 权限被拒 | capability 文件缺 updater:default |
| ADR/注释写着"内网 OTA 不可用" | 基于错误前提,需要撤销并补充正确根因说明 |
一句话外卖
Tauri 2 updater 的安全边界是 ed25519
.sig,不是 TLS;内网 HTTP 端点加dangerousInsecureTransportProtocol: true即可开启 OTA,不需要给每台机器推自签 CA。