# iKuai 4.0 扩展体系统一方案

## 1. 背景

熊哥在设计4.0时，就想所有高级功能模块化安装。裴总也不希望OSPF这些功能固化在系统里——太大了，不适合。现在系统里有两套扩展体系并行，需要统一。

## 2. 现状分析（基于源码）

### 2.1 两套体系对比

| 维度 | AppMarket | PMD |
|------|-----------|-----|
| 实现语言 | Shell (3166行) | C (约15个源文件) |
| 包格式 | .pkg目录 (manifest.json + scripts + files) | JSON描述 + AES加密包 |
| 签名验证 | SHA256 + RSA公钥 (appmarket_plugin_sign_public.pem) | AES-128/256-CBC加密 + MD5校验 |
| 包数据库 | SQLite (/etc/mnt/ikuai/appmarket.db) | JSON + AES加密DB (/etc/log/.__DB) |
| 应用类型 | Docker容器(type=1) + 原生应用(type=0) | 原生二进制 |
| 安装脚本 | PRE_INST.sh / start.sh / POST_INST.sh / stop.sh | install.sh / uninstall.sh + monitor_cmd |
| 完整性校验 | manifest.json签名验证 + 逐文件SHA256校验 | AES解密 + MD5校验 |
| 降级拦截 | `Version $old >= $new` 则跳过 (line 1334) | 无显式降级检查 |
| 更新检查 | sync_apps + __apps_to_cache，从ICC服务器拉列表 | login() → query()，30秒轮询 |
| 进程监控 | 无 | monitor.c probe_all_process() 60秒探测 |
| 自更新 | 不支持 | 支持 (SIGUSR1 → do_reload_binary) |
| 离线安装 | 支持 (本地上传ikp包) | 不支持 (依赖服务器连接) |
| 服务器地址 | ICC云端下发 (applist_control.lua /api/v1/device/plugins) | 硬编码fallback: pkgmgr-v4.ikuai8.com:1864 (routine.c DEF_SERVER_HOST1/2)，OEM定制版用/etc/pmd.d/pmd_host覆盖（zh→packages.sdwan.icnecc.com.cn:1863，HRUI→packages.hruicloud.com:1863），OEM flag=true时fallback到127.0.0.1:1863 |

### 2.2 功能固化现状

以下功能当前固化在固件里，未组件化：

| 功能 | 源码位置 | 体积 | 启动方式 |
|------|----------|------|----------|
| OSPF (frr-reload-c) | packages/ik_apps/frr-reload-c/ | ~50KB C代码 + frr二进制 | rc脚本 boot_load_sync ospf.sh |
| GRE | rootfs/usr/ikuai/script/gre_tunnel.sh | shell脚本 | rc脚本 |
| IPsec | rootfs/usr/ikuai/script/ | shell + 二进制 | rc脚本 |
| Docker | plugins/docker/ | ~50MB | install.sh (已有组件化雏形) |

Docker已经是组件化的（plugins/docker/install.sh + 独立目录），但交付方式还是编译进固件。

### 2.3 问题总结

1. **两套体系重复**：AppMarket和PMD各有一套包管理、签名、数据库、安装脚本逻辑
2. **签名机制不一致**：AppMarket用RSA+SHA256（非对称，更安全），PMD用AES+MD5（对称，密钥泄露风险）
3. **PMD支持自更新和进程监控，AppMarket不支持**——但AppMarket的签名和完整性校验更成熟
4. **OSPF/GRE/IPsec固化在固件里**——裴总不希望，熊哥也想模块化
5. **离线场景**：AppMarket支持本地上传，PMD不支持

## 3. 目标

**一套扩展体系，覆盖OS功能扩展 + 第三方应用**

- 统一包格式（基于AppMarket的manifest.json）
- 统一签名机制（RSA3072 + SHA256）
- 统一安装流程（PRE_INST → install → POST_INST）
- 统一更新机制（PMD的login/query轮询 + 进程监控）
- 统一降级拦截（版本比较，不允许降级）
- 统一离线安装（ICC签发 + 本地上传）

## 4. 技术路径

### 4.1 以AppMarket为基座，吸收PMD能力

AppMarket的签名验证、包格式、SQLite数据库更成熟，作为基座。
PMD的C daemon能力（进程监控、自更新、定期query服务器）合并进来。

```
统一扩展体系
├── 包格式：AppMarket manifest.json + integrity签名
├── 签名：RSA3072 + SHA256 (非对称)
├── 数据库：SQLite (appmarket.db)
├── 安装流程：PRE_INST → start → POST_INST
├── 更新引擎：PMD C daemon (login/query/monitor/自更新)
├── 降级拦截：Version比较 (已有逻辑 line 1334)
└── 离线安装：ICC签发ikp包 → 本地上传 → RSA验证
```

### 4.2 OSPF作为第一个组件化试点

当前OSPF的组成：
- `frr-reload-c`：C写的frr重载工具（packages/ik_apps/frr-reload-c/）
- `ospf.sh` + `ospf` function：启动管理脚本
- `frr`二进制：frrouting套件（zebra/ospfd/ospf6d/staticd）

组件化步骤：
1. 把frr二进制 + ospf.sh + frr-reload-c 打成ikp包
2. manifest.json声明：name=ospf, type=0(原生), version=x.x.x
3. PRE_INST.sh：创建/etc/frr目录，备份旧配置
4. start.sh：启动zebra/ospfd
5. stop.sh：停止zebra/ospfd
6. POST_INST.sh：注册rc启动项

安装后OSP不固化在固件里，通过AppMarket/PMD在线安装或离线上传。

### 4.3 在线更新流程

```
设备启动
├── PMD daemon启动
│   ├── login() → 连接ICC服务器，上报设备信息+已安装包列表
│   ├── 服务器返回：各包最新版本号 + 下载URL
│   ├── query() 30秒轮询（或服务器推送）
│   ├── 发现新版本 → 下载 → RSA验证 → 缓存到本地
│   ├── 通知用户：4.0消息队列 → "组件已更新，需重启生效"
│   └── 下次init时应用（先stop旧版 → 安装新版 → start新版）
│
└── 降级拦截
    ├── PMD缓存latest版本列表
    ├── 本地安装请求 → 比对版本号
    ├── if (请求版本 < 缓存版本) → 拦截，记录日志
    └── 例外：恢复出厂 + 全程离线 / 系统被破解
```

### 4.4 离线安装流程

```
用户在ICC登录
├── ICC根据设备GWID签发ikp包
├── ikp包用RSA3072私钥签名
├── 用户下载ikp包到本地
└── 设备Web界面上传ikp包
    ├── RSA公钥验证签名
    ├── SHA256逐文件校验
    ├── 版本检查（允许同版本重装，不允许降级）
    └── 执行PRE_INST → install → POST_INST
```

### 4.5 PMD与AppMarket合并路径

**第一阶段：共存兼容**
- AppMarket保持现有功能不变
- PMD增加AppMarket签名验证能力（RSA+SHA256）
- PMD的包格式支持manifest.json

**第二阶段：统一入口**
- AppMarket的shell逻辑迁移到PMD C daemon
- PMD统一管理所有包（Docker应用 + 原生应用 + OS组件）
- AppMarket.sh变成PMD的CLI前端

**第三阶段：OSPF组件化**
- OSPF打成ikp包
- 固件出厂不含OSPF，用户按需安装
- 已有OSPF配置的3.0升级4.0设备，自动迁移安装OSPF组件

## 5. 风险评估

### 5.1 OSPF组件化

**风险**：3.0用户升级4.0后OSPF配置丢失
**缓解**：升级脚本检测已有OSPF配置，自动触发OSPF组件安装
**回退**：OSPF组件保留在固件里一个版本周期（4.0.x含OSPF，4.1.x开始组件化）

### 5.2 PMD自更新

**风险**：PMD自身更新失败导致daemon挂掉，所有组件管理瘫痪
**缓解**：PMD保留旧版本备份，更新失败自动回滚（已有do_reload逻辑）
**回退**：固件里保留基础版PMD，可通过sysupgrade恢复

### 5.3 签名密钥管理

**风险**：RSA3072私钥泄露，任何人可伪造ikp包
**缓解**：私钥只在ICC服务器，不在设备上；公钥硬编码在固件
**回退**：固件更新轮换公钥（但离线设备无法更新公钥）

### 5.4 降级拦截

**风险**：用户故意降级到有漏洞的旧版本
**缓解**：PMD缓存服务器下发的最新版本列表，拦截降级请求
**局限**：恢复出厂 + 全程离线可绕过（离线设备确实管不到）

## 6. 实施计划

### 第一批：OSPF组件化试点
- 把OSPF打成ikp包，验证安装/卸载/启动/停止
- 在线安装 + 离线上传都走通
- 降级拦截逻辑验证

### 第二批：PMD吸收AppMarket签名能力
- PMD支持manifest.json + RSA+SHA256验证
- PMD支持AppMarket的PRE_INST/start/POST_INST脚本流程
- 两套体系共存，新的包走PMD，旧的AppMarket包兼容

### 第三批：统一入口
- AppMarket shell逻辑迁移到PMD C daemon
- 一个CLI前端，一套包管理，一套签名，一套数据库
- OSPF/GRE/IPsec逐步组件化

## 7. 3.0遗产利用

naixi-dl上的.hidden-ikuai/是之前PMD插件的遗产。这套机制验证过组件化分发，可以：
- 复用包格式和分发流程
- 升级签名机制（MD5 → RSA3072）
- 升级服务器协议（HTTP → ikstd_prot加密通道）

## 8. 待讨论

1. 包格式统一为ikp还是兼容两种？建议统一ikp（manifest.json + RSA签名）
2. PMD C daemon是否替换AppMarket shell？还是PMD作为后端、AppMarket作为前端？
3. OSPF组件化后，rc启动脚本怎么处理？建议PMD注册启动项，不硬编码在rc里
4. GRE/IPsec是否同步组件化？建议OSPF跑通后再推
5. Docker引擎本身是否也组件化？已有install.sh雏形，可以打ikp包
