Safe Haven 和 F-Droid 不是镜像,是同步后重新扫描的两条线
一句话概括
Safe Haven 会从 F-Droid 和 IzzyOnDroid 同步应用进来,但不是它们的镜像仓库。同步进来的每个 APK 都会经过 Safe Haven 自己的扫描管线,过了才允许出现在公开目录里。
同步是怎么跑的
Safe Haven 的后台有一个叫 Unified Upstream Poller 的调度服务,每六小时跑一轮,处理上限 200 个活跃应用,五分钟内完成。这个调度器对每个应用根据它登记的来源(F-Droid / IzzyOnDroid / GitHub / GitLab / Codeberg)分发到对应的轮询器。
F-Droid 同步规则
- 过滤条件:近 12 个月有更新的应用才进管线
- APK 优先级:arm64-v8a > armeabi-v7a,x86 构建整体排除
- 体积上限:单包 100 MB
- 冲突检测:如果某个包名已经有开发者提交的版本在店里了,同步进来的 F-Droid 版本会被跳过(开发者提交优先)
IzzyOnDroid 同步规则
和 F-Droid 用的是同一套筛选逻辑——12 个月活跃窗口、同样的 ABI 优先级、同样的体积限制。同步进来的条目会打上 izzyondroid 上游标记,客户端能区分它从哪来的。
管理员导入
除了自动同步,管理员也可以直接给一个仓库 URL 手动导入应用,支持 GitHub / GitLab / Codeberg,还能指定资产匹配模式和首选 ABI。
同步进来之后会发生什么
F-Droid / Izzy 的 APK 进来之后,不是直接丢进公开目录,而是走 Safe Haven 自己的完整管线:
- 扫描:过一遍
safehaven-scanner,算哈希、提签名、跑 VX-TITANIUM(如果有)、查本地威胁库 - 签名锁定:首次扫描记录签名哈希
- 版本代码比对:manifest 里的 versionCode 和提交声明的不一致就覆盖或拒绝
- 冲突检测:SHA-256 重复或 versionCode 重复 = 自动拒绝
- 分类标记:打上
fdroid或izzyondroid上游来源标记
全部通过 → 进公开目录。扫描没过 → 被挡住。
为什么签名可能不一样
这是最容易踩的坑。F-Droid 的 APK 是用F-Droid 自己的签名密钥重打包的——这是 F-Droid 的标准操作(因为它要求可复现构建,签名由 F-Droid 统一管理)。IzzyOnDroid 收录的是开发者原生签名的 APK。
所以一个应用在 Safe Haven 里可能有来自三个来源的不同签名:
- 开发者自己提交的:开发者用自己的签名
- IzzyOnDroid 同步来的:开发者原生签名
- F-Droid 同步来的:F-Droid 重打包签名
混装前必须知道的一条
安卓只允许同签名覆盖安装。三个来源签名不同 = 你从 A 装的应用,B 渠道发了新版本,安卓会拒绝覆盖安装,提示"存在签名不同的具有相同包名的应用"。
这不是 Safe Haven 的 bug,是安卓系统的安全机制。处理方式:
- 固定一个渠道:某个应用从哪装的就一直在哪更新,别两边换来换去
- 真要换渠道:先备份应用数据 → 卸载 → 再装另一个渠道的包
- 不要混用不同签名的版本:就算装不上,有些老版本可能被强制降级覆盖,风险很大
和 F-Droid 的定位差异
| 维度 | F-Droid | Safe Haven |
|---|---|---|
| 许可要求 | 必须是自由软件(GPL/MIT 等) | 无硬许可门槛,侧重开源和独立应用 |
| 构建方式 | 可复现构建,F-Droid 自己签名 | 同步的 F-Droid 包保留原签名,开发者提交的用自己的签名 |
| 安全展示 | 构建元数据 + 安全扫描结果 | 五层信任机制(更结构化) |
| 客户端 | F-Droid 客户端 | 独立 Flutter 客户端 |
| 收录规模 | 数千个应用 | 相对较小(早期项目) |
Safe Haven 现在还在早期阶段("early development"),收录量远不如 F-Droid。但它在"信息透明度"这一个维度上做了比 F-Droid 更结构化的展示。
还有 IzzyOnDroid
IzzyOnDroid 收录的是开发者原生签名的 APK,强调可复现构建(Rebuild-Verified)。Safe Haven 从 Izzy 同步进来的包保留开发者签名,所以 Izzy 同步来源的包和开发者自己提交的包签名一致的概率最高。如果一个应用既能从 Izzy 同步也能从开发者提交进来,实际上可能是同一个 APK。