跳转到内容

安全

当前系统用启动、不可变内容、发布元数据三个独立信任域进行认证。开发镜像显式 使用测试密钥;不宣称硬件根信任链或 DATA 加密。

原生 init 认证选定部署,内核要求 root 和 support 的 verity 根哈希签名。 读取时逐块校验,尚未读取的潜在损坏在访问时发现;匹配模块在服务启动前只读挂载。 根及 /var 父目录骨架保持只读,只有明确允许的叶目录绑定 DATA 或有边界的易失存储。

在对应强制验证固件和锚可信时,UEFI Secure Boot 或必需的 FIT 签名保护内核和早期 策略。这与认证硬件的每一个可变启动阶段是不同的保证。

status: shipped — evidence: mica-core:crates/mica-deploy/src/bin/mica-runkit/init.rs, docs/reference/ro-root.md, docs/security/signing.md

更新器在暂存前检查签名的部署描述符、产品与板卡身份和确切对象字节,保留当前与回退对象, 持久化写入后才发布候选,并通过健康门确认。引导固件是独立签名维护产物。 服务器上的文档不签名,也没有有效期:扣住一个发布并不会撤销设备上已经在运行的部署。

元数据锚嵌入已认证内核策略,修改更新源不能替换它们。内容锚的重叠或移除 通过新内核包交付;启动密钥轮换属于启动信任/固件域。每次轮换必须保留可用组合。 不保留历史格式读取器或旧布局迁移。

GET /api/v1/system/info 报告出厂开发标记及其域,这是来源信息,不证明活动固件 正在强制验证。更新状态另报启动/内容验证回执。构建不会隐式生成密钥,签名输入 必须显式提供。

status: shipped — evidence: mica-core:crates/mica-deploy/src/acquisition.rs, mica-core:crates/mica-deploy/src/deployments.rs, docs/security/signing.md

  • **每设备凭据,在设备上铸造。**没有任何设备秘密烘焙进镜像——镜像在全机群 字节相同,烘焙进去的凭据就是全机群共享的秘密。如果工厂 shadow 文件带 可用的密码哈希,构建会失败,两个 profile 都是。
  • **一个例外,按设计公开:出厂热点密钥。**带 Wi-Fi 的产品在每个镜像里都带着 产品密钥;未认领设备开箱即开启热点,其密钥由该产品密钥和标签上印的设备码 推导。持有该产品任一镜像的人,都能凭标签推导出该产品每台设备的这个密钥。 它是首次接触凭据,不是秘密:只在设备被认领之前是热点的密钥,认领会设置热点 自己的密钥(mica-core:docs/factory-ap-key.md)。
  • **范围内任何人都能认领未认领设备。**带蓝牙的未认领设备每次开机后 10 分钟内, 接受手机通过低功耗蓝牙发起的认领,不需要任何凭据,先到者得——与在其网络上 首次访问初始设置一样。首次给设备通电时,请确保无线电范围内(约 10–30 米) 没有外人。
  • **管理 API 是大门。**默认是 8080 上的明文 HTTP,操作员开启后是 8443 上的 HTTPS; 浏览器用密码登录加签名会话和 CSRF 保护,自动化用 bearer token;持久化的登录退避计数器,以及对登录、 初始设置、电源动作和临时密码事件的有边界、fsync 落盘的审计轨迹。
  • **两个 profile 都默认关闭 SSH。**持久访问只凭公钥,且每个授权密钥都是 root 密钥——UI 里原话如此声明。临时 root 密码(由经过认证的管理员 设置,下次启动自动清除)覆盖操作员在台架前的情形,而不产生长寿命 密码。
  • **锁死是真实的。**丢失管理员凭据和所有密钥后没有软件路径可进 (../operate/recovery.md)——这是刻意的取舍:凭据在更新中保留, 意味着更新不是后门。

审计轨迹尚未记录会话生命周期事件,也没有任何东西上传它;没有硬性锁定 阈值(刻意如此,直到存在物理在场的解锁路径)。

status: shipped — evidence: docs/reference/access.md, docs/integrate/provisioning.md, mica-core:docs/factory-ap-key.md, mica-core:docs/ble-provisioning.md

容器以 root 运行(rootless 模式没有构建),随附策略不验证容器镜像签名—— 保护是 registry TLS 和摘要固定,语境是受信任集成商的威胁模型。管理面与 应用的边界是结构性的:MQTT 桥只能到达精确登记的应用服务,永远无法寻址 管理守护进程。见 ../integrate/applications.md。

status: shipped — evidence: docs/integrate/containers.md, docs/integrate/bus.md

一台原装设备的入站面是 8080 上的 apid(开启 HTTPS 后还有 8443)——没有别的东西 为管理而监听,没有东西向外拨号,不存在机群或云通道。静态 UI 资源是公开 的;每一项设备数据和操作都在 API 凭据边界之后。

status: shipped — evidence: docs/reference/remote.md

5.1 防火墙工具,以及并不存在的那道防火墙

Section titled “5.1 防火墙工具,以及并不存在的那道防火墙”

每一个镜像都同时随附 nft 和 iptables。两者都是基座包的依赖,所以即使 一次构建放弃了容器,它们也都在。**镜像交付的是工具,不是策略:没有默认规则集, 没有放行或拒绝清单,也没有任何东西替你管理规则。**它们没有 API,也没有控制台 界面;ssh 加上这两条命令就是全部。

**优先用 nft。**它是设备实际行为的完整视图,也是本产品将来一旦交付策略时所 使用的语汇。iptables 在这里是兼容路径——给那些不会说 nft 的第三方工具和既有 脚本用的——而不是与前者对等的另一个选择。

关于它们有六件事,因为每一件不说清楚都会让人意外。

**iptables 的扩展集合是有界的,而且每块板子都一样。**一条规则若点名了内核未 编入的匹配或目标,会被直接拒绝,并且指名道姓:

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Warning: Extension REDIRECT revision 0 not supported, missing kernel module?

这不是翻译失败,重试也没有用——该扩展根本不在这个内核里;新增一个是内核改动, 不是装个包。

每块板子都保证可用,因为共享内核下限把它们钉住了:目标 MASQUERADE、 REDIRECT、SNAT、DNAT、MARK、CHECKSUM、CT --notrack;匹配 addrtype、conntrack、state、mark;纯裁决(ACCEPT、DROP、RETURN、 跳转)与内建匹配(-p、--dport、-i、-o、--tcp-flags);以及两个地址族 各自的四张表 filter、nat、mangle、raw。

这个集合之外的东西,依赖它之前请先问,并且不要假设两块板子答得一样。 仍有四个扩展存在差异,而且方向并不一致:

uefi-x64 arm64(cx3576)
-m multiport、-m comment、-j CT --zone 拒绝 可用
-j LOG 可用 拒绝

-m limit 与 -m iprange 在两块板子上都被拒绝。-j REJECT 与 -j TCPMSS 今天在两块板上都可用,但下限并没有钉住它们,所以请当作惯例而非契约。如果你的 脚本需要其中任何一个,请提出来——产品究竟保证哪些,是一个尚待决定的问题,不是 疏漏。

**nft list ruleset 是完整视图,iptables -S 不是。**两个工具编程的是同一套 内核子系统 nf_tables。nft list ruleset 打印其中的全部:你通过任一工具添加的 规则,以及容器网络驱动为自己写下的表。iptables -S 只打印经由 iptables 前端 进来的东西,范围是该前端自己拥有的那几张表。在一台跑着容器的设备上,把 iptables -S 读作“这台机器上的防火墙”是错的——而且用它找不到的规则,并不能作为 该规则不存在的证据。

这里的 iptables 是 iptables-nft。在 Debian trixie 上,iptables 命令是 同一套 nf_tables 子系统之上的翻译层,不是旧的 xtables 路径,也不是第二道防火 墙;iptables --version 自己会说:它打印 (nf_tables)。它创建的规则是真正的 nf_tables 规则,落在它自己的表里。旧版二进制(iptables-legacy 及其 save/restore 一对,背后是 xtables-legacy-multi)确实在镜像里,因为同一个 Debian 包就带着它们,而镜像里没有任何东西选中它们:alternatives 组保持在 auto 模式,其中 nft 前端的优先级高于旧版,并且这里没有任何单元、脚本或 postinst 运行 update-alternatives。手工切到旧版,会把你的规则放进第二套、更老的内核规则 存储里,而设备上没有别的东西会去读它——nft 不会,容器驱动也不会。

**容器驱动的表属于容器驱动。**它们通过 nft 可见,通过 iptables 不可见,而且 驱动会持续调谐这些表:你手工改动其中的规则,就是在和一个调谐器较劲,改动会被 重写。要加规则,请加在你自己的链里。

两个工具都不会持久化任何东西。运行时添加的规则只活在内核里,下次重启就没了。 镜像里没有 netfilter-persistent,没有 iptables-save 单元,也没有任何东西会在 启动时载入一份规则集。有一个文件看起来像:nftables 包带来了 /etc/nftables.conf 和 nftables.service,而本镜像刻意让那个单元保持禁用, 用的是自己拥有的一份 preset,而不是靠“少放一个符号链接”。这一点在两个方向上都 重要——那个单元的 ExecStart 是 nft -f /etc/nftables.conf,而该配置以 flush ruleset 开头,所以一旦启用,它会在每次启动时清空容器网络的规则。而且那个 文件位于只读根上,所以它也不是你能放自己规则的地方。

如果你要让一条规则熬过一次断电,今天的路径是你自己的服务:写一个重新施加 规则的服务,用 mica-unit 装到 DATA 上(../../integrate/native-applications.md 第 10 节)。这是对 产品当下行为的陈述,不是关于该如何运行防火墙的建议。

status: shipped — evidence: mica-system-base:debs/mica-system, mica-build:common/kernel/fragments/firewall.fragment, mica-build:src/verify/checks-firewall.ts

生命周期如今被写了下来:产品里的每一份凭据,连同它的负责角色与轮换程序; 发布渠道与签名程序;带分诊与修复目标的严重级别;公告发布;事件响应;以及 支持窗口与生命周期终止。每一节都写明自己的成熟度,而不是暗示它已被强制。 板卡在一份提交进仓库的证据文件里携带启动保障声明,发布门禁读的是那份文件, 不允许一个发布版自称等级。

status: shipped — evidence: docs/security/lifecycle.md, mica-build:boards/cx3576/evidence.json

**其中没有任何一条响应渠道已经存在,这一点应当直接告诉审计者。**仓库根目录 没有公开的安全联系方式与披露政策,没有公告源,没有事件通知路径,也没有任何 工具强制支持窗口或修复目标——今天的报告私下抵达维护者,逐案处理。工厂身份 注入、工厂记录与调试/熔丝策略同样是“已设计、未构建” (../integrate/manufacturing.md)。官方站点的公告简报是 ../../website/security.md;本页就是诚实的清单。

status: unsupported