核心概念:OTA 更新流程
在开始搭建之前,必须理解 Android OTA 更新是如何工作的,这有助于你明白服务器需要提供什么。

-
设备端:
- 检查更新: 设备上的
System Update应用(或Settings中的相关选项)会向服务器发送一个请求,这个请求通常包含设备信息,如:build_id(SP1A.210812.016.C1)build_number(release-keys)device或fingerprint(sailfish或google/sailfish/sailfish:...)incremental(当前构建的增量版本号)
- 获取元数据: 服务器根据设备信息,返回一个描述可用更新的元数据文件(通常是
ota_metadata.json或service.json)。 - 下载更新: 设备解析元数据,获取 OTA 包(通常是
.zip文件)的下载 URL,并开始下载。 - 验证与安装: 下载完成后,设备使用 OTA 包中的
META-INF/com/android/magiskboot.sig(或类似签名) 和payload_properties.txt来验证包的完整性和真实性,设备会进入恢复模式,由recovery.img来执行更新脚本(updater-script)和payload.bin(或update.zip)中的更新操作。
- 检查更新: 设备上的
-
服务器端:
- 接收请求: 接收来自设备的检查更新请求。
- 提供元数据: 根据设备型号和当前版本,返回正确的元数据文件。
- 托管 OTA 包: 提供稳定、可靠的 OTA 包下载链接。
- 安全签名: OTA 包必须使用与设备系统相同的密钥进行签名,否则 Recovery 会拒绝安装。
搭建前的准备工作
-
OTA 包:
- 你需要先准备好一个可用的、已签名的 OTA 更新包,这个包通常是通过
brunch、lineage等第三方 ROM 编译工具生成的,或者是官方 AOSP 提供的官方更新包。 - 关键: 确保这个包已经用正确的密钥(
testkey,shared,release等)进行了签名,你可以用unzip -l update.zip查看其中的文件,如果包含META-INF目录并有签名文件,则说明已签名。
- 你需要先准备好一个可用的、已签名的 OTA 更新包,这个包通常是通过
-
服务器环境:
(图片来源网络,侵删)- 域名: 建议购买一个域名,
ota.yourbrand.com。 - SSL/TLS 证书: 强烈建议使用 HTTPS,现代 Android 系统对 HTTP 的支持越来越严格,使用 HTTPS 可以避免很多问题,你可以使用 Let's Encrypt 提供的免费证书。
- 服务器: 可以是云服务器(如 AWS, Google Cloud, 阿里云, 腾讯云)或自建服务器,配置要求不高,主要考虑带宽和稳定性。
- Web 服务器: 如 Nginx 或 Apache。
- 域名: 建议购买一个域名,
搭建方案(从简到繁)
这里介绍三种主流的方案,你可以根据自己的需求和技术能力选择。
手动静态文件部署(最简单,适合个人或小规模)
这是最基础的方式,核心思想是:服务器只提供文件下载,更新逻辑的判断完全由设备端的脚本完成。
步骤:
-
上传文件:
(图片来源网络,侵删)- 将你的签名好的 OTA 包(
lineage-19.1-20251015-nightly-sailfish.zip)上传到服务器的某个目录,/var/www/ota/sailfish/。 - 将一个用于判断更新的脚本(
update-binary或一个自定义脚本)也一并上传。
- 将你的签名好的 OTA 包(
-
配置 Web 服务器 (以 Nginx 为例):
- 创建一个 Nginx 配置文件,指向你的 OTA 文件目录。
- 确保配置了 HTTPS。
server { listen 443 ssl http2; server_name ota.yourbrand.com; ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; root /var/www/ota; index index.html; # 针对特定设备的 OTA 包 location /sailfish/ { # 允断点续传 alias /var/www/ota/sailfish/; autoindex on; # 可选,用于浏览目录,生产环境建议关闭 } # 或者提供一个统一的下载点 location /download/ { alias /var/www/ota/; } } -
设备端
updater-script逻辑:- 在这种模式下,
updater-script需要自己实现所有逻辑,它会从服务器获取一个版本号文件(version.txt),与设备当前版本比较,如果新版本号更大,则下载zip包并进行安装。
示例
updater-script伪代码:getprop ro.build.date.utc # 获取设备当前构建时间戳 http_download("https://ota.yourbrand.com/sailfish/version.txt", "/tmp/version.txt") file_read_line("/tmp/version.txt", "/tmp/new_version.txt") if /tmp/new_version.txt > ro.build.date.utc then ui_print("发现新版本,开始下载...") http_download("https://ota.yourbrand.com/sailfish/lineage-19.1-...zip", "/tmp/update.zip") package_extract_dir("tmp/update.zip", "/system") ... ui_print("更新完成,正在重启...") reboot_now else ui_print("已是最新版本。") endif- 缺点: 不灵活,每次添加新设备或新版本都需要修改脚本并重新打包,无法实现“设备自动识别”的通用 OTA。
- 在这种模式下,
使用开源 OTA 服务器框架(推荐,功能完善)
这类框架(如 OmniRom 的 ota_server)为你处理了大部分逻辑,你只需要提供 OTA 包和配置文件即可。
以 omnirom/ota_server 为例 (Python 编写):
-
环境准备:
- 服务器上安装 Python 3, Git, Nginx。
- 克隆仓库:
git clone https://github.com/omnirom/ota_server.git
-
配置:
- 进入
ota_server目录,编辑config.py文件,这是核心配置文件,你需要定义:SERVER_URL: 你的 OTA 服务器域名。BUILDS: 一个字典,定义每个设备有哪些可用的构建。DEVICES: 设备列表。SIGNATURE: 用于验证下载的密钥指纹。
# config.py 示例 SERVER_URL = "https://ota.yourbrand.com" BUILDS = { "sailfish": { # 设备代号 "191": { # 版本号 "filename": "lineage-19.1-20251015-nightly-sailfish.zip", "url": SERVER_URL + "/builds/sailfish/lineage-19.1-20251015-nightly-sailfish.zip", "timestamp": 1697356800, # 时间戳 "md5": "d41d8cd98f00b204e9800998ecf8427e", # MD5 或 SHA256 "size": 815885896, } } } DEVICES = ["sailfish", "marlin"] # 支持的设备列表 SIGNATURE = ["testkey"] # 允许的签名密钥 - 进入
-
上传文件:
- 将你的 OTA 包上传到
ota_server/public_html/builds/目录下,并根据config.py中的路径进行组织。
- 将你的 OTA 包上传到
-
启动 Web 服务:
- 框架通常自带一个简单的 Web 服务器(如 Flask)。
- 运行
python ota_server.py。 - 配置 Nginx 作为反向代理,将请求转发给这个 Python 应用。
server { listen 443 ssl http2; server_name ota.yourbrand.com; ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; location / { proxy_pass http://127.0.0.1:5000; # 假设 ota_server.py 监听 5000 端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 直接提供 OTA 包下载 location /builds/ { alias /path/to/ota_server/public_html/builds/; autoindex on; } } -
工作流程:
- 设备请求
https://ota.yourbrand.com/?device=sailfish&version=191。 - Python 应用根据
config.py生成service.json文件并返回。 - 设备解析
service.json,找到url字段,然后从https://ota.yourbrand.com/builds/...下载 OTA 包。
- 设备请求
- 优点: 功能强大,支持多设备、多版本、MD5/SHA256 校验、增量更新等,配置灵活。
- 缺点: 需要一定的 Python 和 Linux 操作能力。
使用商业 OTA 服务(最省心,适合企业)
如果你不想自己维护服务器,可以考虑商业 OTA 服务。
-
代表产品:
- Firebase App Distribution: 主要用于 App 分发,但可以配合一些自定义实现简单的 OTA。
- AWS Device Farm: 提供设备管理和测试,不直接提供 OTA 托管。
- 专业的第三方 OTA 平台: 市面上有一些专门为 IoT 或 Android 设备提供 OTA 服务的 SaaS 公司。
-
优点:
- 无需关心服务器维护、带宽、安全等问题。
- 通常提供完善的 Web 管理界面,可以轻松管理不同设备的更新包。
- 提供数据分析、设备分组、灰度发布等高级功能。
-
缺点:
- 成本高昂,通常按设备数或流量收费。
- 定制化程度较低,受限于服务商提供的功能。
安全最佳实践
- 强制 HTTPS: 必须使用 HTTPS,防止中间人攻击和流量劫持。
- 签名验证: 确保 OTA 包在生成时已正确签名,设备在安装前会自动验证签名,这是最基本的安全保障。
- 文件校验: 在元数据中提供文件的 MD5 或 SHA256 哈希值,设备下载后可以进行二次校验,确保文件在传输过程中未被损坏或篡改。
- 访问控制: 如果你的 OTA 是私有的,可以在 Nginx 层面设置认证(如 HTTP Basic Auth),或者要求设备在请求中携带特定的 Token。
- 最小权限原则: 运行 Web 服务器的用户(如
www-data)应该只拥有对 OTA 文件目录的读取权限,没有写入或执行权限。
总结与建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 手动静态部署 | 简单、快速、零依赖 | 不灵活、难维护、功能少 | 个人玩客、一次性更新、测试环境 |
| 开源框架 | 功能强大、灵活、可定制 | 需要技术能力、自己维护 | 开源 ROM 社区、有一定技术实力的个人或小团队 |
| 商业服务 | 省心、稳定、功能全面 | 成本高、定制化低 | 企业产品、商业项目、大规模设备部署 |
给你的建议:
- 如果你是个人开发者或爱好者: 从 方案二(开源框架) 开始是最好的选择,它能让你以较低的成本获得一个功能相对完善的 OTA 系统,并且能让你深入了解其工作原理。
- 如果你是商业团队: 直接考虑 方案三(商业服务),将精力更多地投入到产品本身,而不是基础设施的维护上。
搭建 OTA 服务器是一个实践性很强的过程,建议你在测试环境(如虚拟机或云服务器上的免费实例)上反复尝试,熟悉了流程后再部署到生产环境,祝你成功!
