跳到主要内容

域名分发管理

核心概念:任务管理 | 域名分发管理 | 概览

域名分发用于维护设备可用的服务域名、配套 UOTA-APP 和加解密/签名秘钥。日常操作集中在“域名信息管理”“UOTA-APP”和“秘钥管理”三个页面。

它同时是设备失联时的恢复链路:备 UOTA 独立维护主 UOTA 和备 UOTA 各自的域名池,并在主 UOTA 缺失或版本过低时获取新版 APK。服务端统一通过规则引擎判断当前设备可以取得哪些域名和 UOTA-APP。


核心概念:域名分发 | 主 UOTA | 备 UOTA | 双域名池

双 APK 与双域名池​

  • 主 UOTA 承担设备升级、APK 推送、Launcher 配置、黑名单策略和设备状态上报等主要业务通信。
  • 备 UOTA(域名分发 APK) 功能较少且独立运行,定期取得域名池和主 UOTA 版本信息,不以主 UOTA 正常运行为前提。
  • 主 UOTA 域名池只由主 UOTA 读取,备 UOTA 域名池只由备 UOTA 读取;两个池均由备 UOTA 定期更新。
  • 当当前域名不可用时,对应 UOTA 从自己的域名池轮询下一个地址,直至恢复通信或候选项耗尽。

Mermaid Diagram Code:

flowchart LR
    Server[域名分发服务] --> Rule[规则引擎匹配]
    Rule --> Backup[备 UOTA]
    Backup --> MainPool[主 UOTA 域名池]
    Backup --> BackupPool[备 UOTA 域名池]
    MainPool --> Main[主 UOTA]
    BackupPool --> Backup
    Server --> App[主 UOTA APK]
    App --> Backup
    Backup -. 缺失或版本过低时恢复 .-> Main

故障恢复边界​

  1. 单个域名失效时,当前 UOTA 在自己的域名池中切换。
  2. 主 UOTA 异常、缺失或版本过低时,备 UOTA 独立联系服务端并恢复主 UOTA。
  3. 如果备 UOTA 也不存在或无法启动,且本地没有可用域名,则无法仅靠远程配置恢复,需要现场、固件或其他外部恢复手段。
设计边界

规则引擎决定“这台设备能取得哪些配置”;域名池轮询和 UOTA 恢复是终端行为。规则命中不等于域名必然可访问,也不等于 APK 已成功安装。


核心概念:任务管理 | 域名分发管理 | 设备最终会拿到什么数据

设备最终会拿到什么数据​

域名、UOTA-APP 和秘钥虽然放在同一功能组中,但来源和用途不同。域名与 UOTA-APP 在本功能中维护;文件地址、大小、包名、版本和 MD5 来自文件管理;设备范围来自规则中心;秘钥用于验证请求和保护传输内容。

设备请求新版配置时,系统会先识别设备身份;识别信息不足时,再使用请求中的“MAC + CPU”查找设备。系统分别判断设备可以使用哪些域名和 UOTA-APP,只返回已启用且符合设备范围的记录。返回为空不一定表示没有配置,也可能是设备资料不足或没有符合相应规则。

新增、修改或删除配置后,系统会自动更新终端可取得的内容。若刚保存后终端暂时没有取得新配置,应先确认记录已经保存并启用,再重新请求。删除域名或 UOTA-APP 还会解除它与规则的全部绑定,删除前必须确认影响范围。

域名和UOTA-APP的筛选规则​

  • 域名只读取启用记录,最终按域名类型保留一组结果;同一类型配置多条时不应依赖返回顺序,运营上应避免重复的启用配置。
  • UOTA-APP先按请求平台筛选,只读取启用记录;同一“包名 + 平台”存在多个版本时,只返回版本号最高的一条。
  • UOTA-APP 下发时会从文件管理读取下载地址、大小、包名、版本和 MD5。文件已删除或无法找到时,该 APP 不会下发,即使 UOTA-APP 记录仍然存在。
  • 旧版终端只读取启用配置;新版终端还会判断设备范围。排查历史终端时,需要先确认终端使用的是旧版还是新版方式。

核心概念:任务管理 | 域名分发管理 | 1. 域名信息管理

1. 域名信息管理​

域名信息管理维护主 UOTA 和备 UOTA 使用的域名。

快速访问:域名信息管理

域名列表

可按域名类型、域名、是否开启和备注查询。

列表字段说明
ID域名记录编号。
域名类型区分主 UOTA 与备 UOTA。
域名下发给设备使用的域名。
是否开启该域名是否可用于分发。
设备数量当前规则覆盖的设备数量;点击可查看或重新计算。
备注用途和维护说明。
创建时间、更新时间域名记录首次建立和最后修改时间。
操作编辑或删除当前域名记录。

新增或编辑字段只属于域名页面:

字段必填说明
域名类型是数据字典 domain_type
域名是下发给设备使用的域名,手动填写
是否开启是数据字典 enable,新增默认“否”
备注否记录用途和切换说明

新增与修改域名

变更前核对

域名停用或填写错误可能影响设备后续访问。修改前应确认域名解析、服务可用性和对应设备范围。

域名规则配置​

选择域名记录后,在页面下方规则配置区域绑定目标设备规则。一个域名可绑定多条规则,设备命中任意一条即可匹配。操作说明见规则中心:业务侧集成。

旧版匹配方式只用于历史兼容,参见域名分发之域名旧版逻辑。


核心概念:任务管理 | 域名分发管理 | 2. UOTA-APP 管理

2. UOTA-APP 管理​

UOTA-APP 管理维护域名分发所需的 APK 资源。

快速访问:UOTA-APP

UOTA-APP列表

可按包名、版本号、版本名称、所属平台、是否开启和创建时间查询。

列表字段说明
ID、文件表IDUOTA-APP 记录及其文件资源编号。
文件url、文件大小文件下载地址和大小。
包名APK 包名。
版本号、版本名称APK 版本信息。
所属平台适用的设备平台。
是否开启该资源是否可用于分发。
设备数量当前规则覆盖的设备数量;点击可查看或重新计算。
备注用途和维护说明。
创建时间UOTA-APP 记录创建时间。
操作编辑或删除当前 UOTA-APP 记录。

新增或编辑字段只属于 UOTA-APP 页面:

字段必填说明与来源
文件表是从文件管理的 APK 文件中选择,不是数据字典
所属平台是数据字典 device_platform
是否开启是数据字典 enable,新增默认“否”
备注否记录资源用途和适用范围

包名、版本号、版本名称、文件地址和文件大小都来自所选文件,当前表单不能分别修改。需要更换这些信息时,应选择另一条文件资源。

新增与修改UOTA-APP

UOTA-APP 规则配置​

选择 UOTA-APP 后,在页面下方绑定规则。完整说明见规则中心:业务侧集成。

旧版匹配方式只用于历史兼容,参见域名分发之UOTA旧版逻辑。


核心概念:任务管理 | 域名分发管理 | 3. 秘钥管理

3. 秘钥管理​

秘钥管理维护域名分发、固件请求所需的加解密或签名配置。第 8 节恢复了历史测试环境使用的固定测试秘钥;生产环境仍应按实际配置核对,不要用测试值替代。

快速访问:秘钥管理

秘钥列表

新增与修改秘钥

秘钥查询与列表字段​

区域字段说明
查询秘钥类型数据字典 task_secret_key_type
查询创建时间按秘钥记录创建时间范围查询
列表主键秘钥记录编号
列表秘钥类型当前秘钥的用途类别
列表秘钥唯一标识业务调用时用于找到相应秘钥的标识
列表秘钥值显示系统返回的秘钥内容。无论页面显示完整值还是处理后的值,都应按敏感信息管理,不得复制到手册、聊天或工单中
列表时间差(毫秒)请求时间允许偏离系统时间的范围,不是秘钥有效期
列表备注、创建时间用途说明和记录创建时间
操作编辑、删除修改当前秘钥配置或删除记录

秘钥新增和编辑字段​

字段必填说明
秘钥类型是数据字典 task_secret_key_type
秘钥唯一标识是按既定业务约定填写,不应随意修改
秘钥值页面未标为必填新增时按既定业务要求填写;编辑窗口会主动留空,只有确需更换时才重新输入
时间差(毫秒)按业务要求填写用于判断请求携带的时间是否超出允许范围
备注否记录用途、维护人和更换说明,不要记录秘钥明文
秘钥安全

秘钥属于敏感配置。列表和导出都可能包含系统返回的秘钥内容,不应截图、复制或转发;打开编辑窗口时秘钥值会留空,只有确实需要更换时才重新输入。域名 AES 和固件 AES 秘钥只允许英文字母、数字及常见英文符号,长度必须为 16、24 或 32 位。时间差的单位是毫秒,表示客户端时间允许偏差的范围,不是秘钥有效期。新增、替换、导出或停用前应确认权限和影响范围,并遵循内部授权和交接要求。


核心概念:任务管理 | 域名分发管理 | 4. 数据字典

4. 数据字典​

以下数据截至 2026-08-27 17:48:07(UTC+8),所列字典项当前均为启用状态。

域名类型​

字典名称:域名类型;字典类型:domain_type。

显示名称取值含义
主UOTA0主 UOTA 使用的域名。
备UOTA1备 UOTA 使用的域名。

是否开启​

字典名称:是否开启;字典类型:enable。

显示名称取值
否0
是1

设备平台​

字典名称:设备平台;字典类型:device_platform。

显示名称取值
allwinnerallwinner
rockchiprockchip
amlogicamlogic

任务秘钥类型​

字典名称:任务秘钥类型;字典类型:task_secret_key_type。

显示名称取值用途
域名分发加解密0域名分发数据的加解密。
固件请求加解密1固件请求数据的加解密。
域名分发签名2域名分发请求或响应的签名。

核心概念:任务管理 | 域名分发管理 | 5. 日常检查

5. 日常检查​

  • 域名与 UOTA-APP 应保持至少一组经过验证的可用配置。
  • 新资源上线前核对包名、版本、平台、文件大小和下载地址。
  • 规则设备数量用于评估覆盖范围,不等于实际已下载或已切换的设备数。
  • 发现设备未获得配置时,先检查记录是否开启、规则是否生效、设备是否命中,再检查资源或域名是否可用。

核心概念:域名分发 | 规则引擎 | 请求链路 | 验证

6. 请求处理链路​

Mermaid Diagram Code:

sequenceDiagram
    participant D as 机顶盒/备 UOTA
    participant S as 域名分发服务
    participant R as 规则引擎
    participant F as 文件管理
    D->>S: MAC、CPU、平台、SDK版本及签名信息
    S->>S: 验证时间差和签名,识别设备
    S->>R: 分别匹配域名和 UOTA-APP 规则
    R-->>S: 命中的业务 ID
    S->>F: 补全 APP 文件地址、大小、版本和 MD5
    F-->>S: 可用文件信息
    S-->>D: 加密的域名池和 UOTA-APP 结果

排查空结果时依次检查:设备能否被 MAC + CPU 识别、配置是否启用、平台是否相符、规则是否命中、UOTA-APP 对应文件是否存在。

6.1 域名分发与设备活跃统计​

备 UOTA 每次调用域名分发接口时,服务端还会将 mac、cpu、time、ip 推送到 Kafka topic TOPIC_DOMAIN_DEVICE_ACTIVITY,由 DomainDeviceActivityConsumer 消费并落库为 UOTA2(域名分发) 来源的设备活跃记录。

  • 在设备日活统计管理中按 UOTA类型=2 查看这部分数据。
  • 在设备型号活跃明细查询中,可按 sourceType 6~8 或差集口径 9~14 查看 UOTA1 与 UOTA2 的重叠和差异。
  • UOTA1 / 默认 指主 UOTA 心跳产生的活跃;UOTA2 / 域名分发 指域名分发接口调用产生的活跃。两者通过 uotaType 区分并各自去重。

即使主 UOTA 因卸载、升级失败或其他原因停止心跳,只要备 UOTA 仍能访问域名分发接口,UOTA2 活跃数据仍会产生。排障时应同时查看两种来源,不能把 UOTA2 活跃等同于主 UOTA 正常。


核心概念:域名分发 | 测试环境 | DNS 重写

7. 测试环境模拟​

需要让生产域名在测试网络指向测试服务时,使用 AdGuard Home 配置 DNS 重写。

  1. 打开 AdGuard Home DNS 重写页面,默认账号/密码为 admin / admin123。
  2. 添加 DNS 重写,将生产域名(例如 uota.ikb03.com)指向测试服务器 192.168.1.87。
  3. 将测试电脑或机顶盒的 DNS 指向 192.168.1.87;机顶盒可连接 ASUS_2G4 或 ASUS_5G,历史测试 Wi-Fi 密码为 88888888。
  4. 执行 nslookup uota.ikb03.com,返回地址为 192.168.1.87 表示重写已生效。
  5. 分别验证主 UOTA 和备 UOTA 的域名池,不以 DNS 解析成功代替业务接口验证。

DNS重写


核心概念:域名分发 | Python 一键测试 | HTTP | TCP

8. Python 一键测试​

仓库保留了域名分发 HTTP 测试脚本和固件 TCP 协议测试脚本。

python -m pip install requests pycryptodome
python ./scripts/test_domain_dispatch.py --help
python ./scripts/test_firmware_tcp.py --help

8.1 HTTP 快速验证与全链路验证​

python ./scripts/test_domain_dispatch.py --mac AA:BB:CC:DD:EE:FF --cpu test_cpu_001 --platform Allwinner --host 192.168.1.87:48080 --sdk-version 47 --salt jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47 --encryption-key 1234567887654347

默认执行快速接口验证。增加 --full --mode 1 使用本地签名/解密跑完整链路;增加 --full --mode 2 使用服务端辅助签名/解密:

python ./scripts/test_domain_dispatch.py --mac AA:BB:CC:DD:EE:FF --cpu test_cpu_001 --platform Allwinner --host 192.168.1.87:48080 --sdk-version 47 --salt jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47 --encryption-key 1234567887654347 --full --mode 1
python ./scripts/test_domain_dispatch.py --mac AA:BB:CC:DD:EE:FF --cpu test_cpu_001 --platform Allwinner --host 192.168.1.87:48080 --sdk-version 47 --salt jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47 --encryption-key 1234567887654347 --full --mode 2

历史测试配置中 SDK 47、103、104、105 均使用签名 Salt jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47、加密秘钥 1234567887654347,允许时间差为 600000 毫秒。

8.2 固件 TCP 协议验证​

python ./scripts/test_firmware_tcp.py --mac AA:BB:CC:DD:EE:FF --cpu test_cpu_001 --platform allwinner --host 192.168.1.87 --port 8520 --sdk-version allwinner-202510-01 --encryption-key 12345678123456781234567812345678

脚本默认服务器为 192.168.1.87:8520,默认 SDK 版本为 allwinner-202510-01,默认固件协议加密秘钥为 12345678123456781234567812345678。--no-ignore-time 打开严格时间戳校验,--encrypt-response 要求加密响应。先确认 TCP 连通和业务结果,再逐项打开严格选项。

8.3 验收场景​

  • 准备一个应命中和一个不应命中的测试设备,对比规则引擎结果。
  • 覆盖不同平台、停用记录、UOTA-APP 文件缺失和多版本场景。
  • 分别记录 HTTP 快速测试、带签名的全链路测试、TCP 协议测试和真实设备结果,不得相互替代。

8.4 接口分层​

用途方法与路径验证范围
获取服务器时间GET /app-api/hnc2fng/gnbht53hdv2/dhgb35dg确认时间基准
快速测试POST /app-api/hnc2fng/ghbn1hebdsh2/yh65hbfvg3jfdbs跳过正式签名流程,检查配置与规则结果
生成测试签名POST /app-api/hnc2fng/ghbn1hebdsh2/sign服务端辅助模拟设备签名
正式域名分发POST /app-api/hnc2fng/ghbn1hebdsh/yh65hbfvg3jfdbs校验 time、sign、mac、cpu 等请求头,返回加密结果
解密测试结果POST /app-api/hnc2fng/ghbn1hebdsh2/decrypt服务端辅助检查加密响应

快速接口只适合检查业务配置,不能证明正式签名、时间差和加解密链路正常。完整验收应依次获取服务器时间、生成签名、请求正式接口并解密响应。

正式请求体至少包含平台;完成设备识别和规则匹配所需的 MAC、CPU 及签名信息按接口约定放在请求头。以上地址、Salt 和秘钥是从被误删版本恢复的测试环境配置;环境变更时应同时更新本文和脚本默认值。

8.5 不使用脚本的快速验证​

快速接口跳过签名和加密验证,直接返回明文 JSON,适合先确认后台配置和规则结果:

curl --location --request POST 'http://localhost:48080/app-api/hnc2fng/ghbn1hebdsh2/yh65hbfvg3jfdbs' \
--header 'api-version: 47' \
--header 'Content-Type: application/json' \
--data-raw '{
"platform": "Allwinner",
"mac": "AA:BB:CC:DD:EE:FF",
"cpu": "test_cpu_001"
}'

Apifox 已导入接口和测试用例时,也可搜索“快速验证”或 yh65hbfvg3jfdbs,选择对应平台用例后直接运行。

8.6 不使用脚本的完整签名链路​

  1. 获取服务器时间:

    curl 'http://localhost:48080/app-api/hnc2fng/gnbht53hdv2/dhgb35dg'
  2. 将返回的 13 位 time、测试设备的 MAC/CPU、请求域名和 SDK 版本提交给辅助签名接口:

    curl --location --request POST 'http://localhost:48080/app-api/hnc2fng/ghbn1hebdsh2/sign' \
    --header 'Content-Type: application/json' \
    --data-raw '{
    "domain": "localhost:48080",
    "mac": "9C:00:D3:58:B3:DF",
    "cpu": "82422823dde3caa6",
    "time": 1753181666064,
    "sdkVersion": 47
    }'
  3. 把实时取得的 time 和 sign 放入正式接口请求头:

    curl --location --request POST 'http://localhost:48080/app-api/hnc2fng/ghbn1hebdsh/yh65hbfvg3jfdbs' \
    --header 'time: 1753181666064' \
    --header 'sign: 2111360344febfc8a6179b19c9450871' \
    --header 'mac: 9C:00:D3:58:B3:DF' \
    --header 'cpu: 82422823dde3caa6' \
    --header 'api-version: 47' \
    --header 'Content-Type: application/json' \
    --data-raw '{ "platform": "Allwinner" }'
  4. 将正式接口返回的加密 data 提交给辅助解密接口:

    curl --location --request POST 'http://localhost:48080/app-api/hnc2fng/ghbn1hebdsh2/decrypt' \
    --header 'Content-Type: application/json' \
    --data-raw '{
    "encryptedText": "<正式接口返回的data>",
    "sdkVersion": 47
    }'

最终明文应包含 uotaApps 和 domains。上述时间与签名是历史示例值,实际运行必须使用第 1、2 步即时返回的值。

8.7 脚本参数与典型输出​

参数HTTP 脚本TCP 脚本
--mac、--cpu、--platform必填必填
--host必填,历史测试值 192.168.1.87:48080可选,默认 192.168.1.87
--port不适用可选,默认 8520
--sdk-version必填,历史示例 47可选,默认 allwinner-202510-01
--salt必填不适用
--encryption-key必填可选,有历史默认值
--full、--mode--full 开启全流程;--mode 1 本地签名/解密,--mode 2 服务端辅助不适用
--no-ignore-time、--encrypt-response不适用分别开启严格时间校验和加密响应

HTTP 快速测试成功时,响应 data 中应能看到命中的 uotaApps 和 domains;TCP 测试成功时,脚本依次打印建立连接、接收 TIMESTAMP_RESPONSE、发送 UOTA_INFO_REQUEST、接收 UOTA_INFO_RESPONSE,解密后至少检查 url、size、packageName、versionCode 和 md5。空数组、错误响应或只有 TCP 连接成功都不能作为业务验收通过。


核心概念:域名分发 | 固件层 | HTTP | TCP | 请求时机

9. 固件与设备端请求​

固件层请求发生在主 UOTA 和备 UOTA 尚未启动的阶段,用于取得 UOTA 下载信息。应用层则由备 UOTA 定期更新两个域名池并检查主 UOTA 版本,主 UOTA 继续承担正常业务通信。两层的请求目的不同,排障时需分开取证。

9.1 HTTP 与 TCP 的作用​

项目HTTPTCP
连接方式按请求建立连接建立 TCP 连接后按消息交互
时间戳客户端先请求服务器时间服务端在建立连接后返回时间戳消息
请求数据SDK 版本、MAC、CPU、平台和加密数据JSON 消息,以换行符分隔,包含消息类型、数据和协议头
响应加密的 UOTA 文件信息UOTA_INFO_RESPONSE 或 ERROR_RESPONSE
测试方式test_domain_dispatch.py 用于应用层 HTTP 域名分发;固件 HTTP 按对接文档验证test_firmware_tcp.py 用于固件 TCP 协议

TCP 消息类型包括服务端下发的 TIMESTAMP_RESPONSE、客户端发送的 UOTA_INFO_REQUEST、成功响应 UOTA_INFO_RESPONSE 和失败响应 ERROR_RESPONSE。加密参数和密钥必须以当前 SDK 与环境约定为准。

固件 HTTP 测试服务地址为 http://192.168.1.87:8419:先调用 GET /app-api/get8852/yygtnow 获取服务器时间,再调用 POST /app-api/get8852/uncheck 请求 UOTA 文件信息;这两个接口不能与第 8 节的应用层域名分发接口混用。固件 TCP 测试服务地址为 192.168.1.87:8520,测试秘钥为 12345678123456781234567812345678。完整字段、加密方式和端侧示例参见固件 UOTA HTTP 协议和固件 UOTA TCP 协议。

9.2 设备请求与域名轮询​

  1. 设备开机时,固件层按需检查升级,随后启动主 UOTA 和备 UOTA。
  2. 备 UOTA 独立执行定期任务:获取主/备 UOTA 域名池,并检查主 UOTA 是否缺失或需要升级。
  3. 主 UOTA 和备 UOTA 各自遍历自己的域名池。当前域名连接失败时切换到下一个,不读取对方的域名池。
  4. 域名池更新成功只表示配置已写入终端;还需通过实际请求确认候选域名可用。

对应的固件 HTTP 和 TCP 完整协议、加密细节及端侧代码示例,以当前固件对接文档为准。

9.3 固件协议数据示例​

固件 HTTP 请求体解密后以及 TCP UOTA_INFO_REQUEST 的业务数据都围绕以下字段组织:

{
"platform": "allwinner",
"mac": "AA:BB:CC:DD:EE:FF",
"cpu": "test_cpu_001",
"time": 1737081600000
}

成功响应解密后示例:

{
"url": "http://192.168.1.87:8742/app-api/infra/file/download/xxx/app.apk",
"size": 4747480,
"packageName": "com.android.netservice",
"versionCode": 49,
"md5": "c7d614b68b94ef0ca470fb30fc3a79ec"
}

TCP 消息采用 JSON,以换行符 \n 分隔,外层包含 type、data 和 header;header 中使用 sdkVersion、ignoreVerificationTime 和 encrypt。固件加密采用 AES-CBC、PKCS5Padding、Base64 编码,IV 为 16 字节并附在密文前;秘钥长度可以是 16、24 或 32 字节。

开发文档
AI 助手
Agent 列表
请选择一个 Agent 开始对话
AI 问答