4. ROS2安全架构

ROS2 在 DDS 安全规范之上构建了 SROS2(Secure ROS 2)安全体系,目标是在不改变节点通信 API 的前提下,为话题、服务、动作和参数提供身份认证、数据加密与访问控制。理解 SROS2 的关键,不是记住某个命令,而是看清“身份—权限—密钥—分发”四者如何协同:每个节点属于一个安全 enclave,enclave 决定它拥有哪些密钥和权限文件,权限文件再约束它能发布、订阅或调用哪些接口。

一、核心原理:SROS2 的四个组件

SROS2 并不是一个独立中间件,而是对 DDS Security 的封装与工具链。它主要由四类组件构成:

  • 安全插件(Security Plugins):由 DDS 实现提供,负责认证、加密、访问控制等底层安全操作,ROS2 通过 RMW 层调用。
  • keystore(密钥库):由 ros2 security 命令生成的目录结构,保存 CA 证书、各 enclave 的私钥、证书和权限文件。
  • enclave(安全域):一个逻辑安全边界,通常对应一个节点、一组节点或一个功能模块,是权限和密钥的最小管理单元。
  • 权限文件(permissions.xml):以 XML 描述该 enclave 允许的发布、订阅、调用等行为,是访问控制的直接依据。

节点启动时,RMW 会读取环境变量 ROS_SECURITY_KEYSTORE 和 ROS_SECURITY_ENCLAVE_OVERRIDE,定位自己的 enclave,加载私钥、证书和权限文件,再与对端完成身份认证。认证通过后,通信数据按策略进行加密或签名。

二、安全 enclave 与访问控制策略

enclave 是 SROS2 中最容易被误解的概念。它不是“一个节点只能有一个 enclave”,而是“一个 enclave 可以覆盖多个节点”。例如,可以把整个导航模块放在 /navigation enclave 下,也可以为每个节点单独建 enclave。enclave 路径通常以 / 开头,如 /talker、/robot/sensors。

访问控制策略由 permissions.xml 定义,核心是“允许列表”模型:默认拒绝,只有显式声明的操作才被允许。常见规则包括:

  • publish:允许向指定话题发布消息。
  • subscribe:允许订阅指定话题。
  • call:允许调用指定服务。
  • execute:允许执行指定动作。

权限文件还支持通配符和条件,但生产环境应尽量精确到具体话题名,避免使用 * 造成越权。下面是一个简化示例:

<permissions>
  <grant name="talker">
    <allow rule="publish">
      <topic>/chatter</topic>
    </allow>
    <allow rule="subscribe">
      <topic>/status</topic>
    </allow>
  </grant>
</permissions>

三、密钥存储与分发机制

keystore 的典型结构如下:

keystore/
├── ca.cert.pem
├── ca.key.pem
├── identity_ca.cert.pem
├── permissions_ca.cert.pem
└── enclaves/
    ├── talker/
    │   ├── cert.pem
    │   ├── key.pem
    │   ├── governance.p7s
    │   └── permissions.p7s
    └── listener/
        ├── cert.pem
        ├── key.pem
        ├── governance.p7s
        └── permissions.p7s

其中 ca.* 是根证书与私钥,identity_ca 和 permissions_ca 分别用于签发身份证书和权限文件。每个 enclave 目录下的 cert.pem、key.pem 是节点身份凭证,governance.p7s 和 permissions.p7s 是签名后的治理与权限文件。

分发机制有两种常见方式:一是把 keystore 目录整体拷贝到目标设备,通过环境变量指向;二是只分发某个 enclave 子目录,配合 ROS_SECURITY_ENCLAVE_OVERRIDE 指定路径。无论哪种方式,私钥 key.pem 都不应出现在版本库或镜像中,应使用安全通道传输并限制文件权限。

建议在 CI 中只生成证书和权限文件,私钥由设备首次启动时本地生成或通过安全注入,避免私钥在构建产物中扩散。

四、典型场景与操作流程

假设有一个 talker 和一个 listener,需要开启安全通信。基本流程如下:

  1. 创建 keystore:ros2 security create_keystore keystore
  2. 为 talker 创建 enclave:ros2 security create_enclave keystore /talker
  3. 为 listener 创建 enclave:ros2 security create_enclave keystore /listener
  4. 编辑权限文件,分别允许 talker 发布 /chatter、listener 订阅 /chatter。
  5. 签名权限文件:ros2 security sign_permissions keystore /talker
  6. 设置环境变量并启动节点:
export ROS_SECURITY_KEYSTORE=$PWD/keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker
ros2 run demo_nodes_cpp listener --ros-args --enclave /listener

如果权限文件未签名或策略不匹配,节点会启动失败或通信被拒绝。此时应检查 ROS_SECURITY_STRATEGY 是否为 Enforce,以及 permissions.p7s 是否与当前 enclave 匹配。

五、常见误区与复盘

误区 后果 正确做法
所有节点共用一个 enclave 权限过大,一处泄露影响全局 按功能或节点拆分 enclave
权限文件使用通配符 * 越权发布/订阅难以审计 精确到具体话题和服务名
私钥提交到 Git 身份可被伪造 私钥不入库,安全注入
只开加密不配权限 未授权节点仍可加入 同时启用认证与访问控制

复盘时可用 ros2 security list_enclaves keystore 查看已有 enclave,用 ros2 security generate_artifacts 批量生成策略。真正稳定的安全部署,依赖的是清晰的 enclave 划分、最小权限的 permissions.xml,以及私钥全生命周期的受控管理。

SROS2 安全架构:enclave、权限与密钥分发 keystore ca.cert.pem identity_ca / permissions_ca enclaves/ 目录 enclave /talker cert.pem / key.pem governance.p7s permissions.p7s enclave /listener cert.pem / key.pem governance.p7s permissions.p7s permissions.xml allow publish /chatter allow subscribe /status DDS Security 认证 / 加密 / 访问控制 RMW 层调用 节点通信 talker → /chatter listener ← /chatter 分发路径:keystore → 目标设备 → 环境变量 ROS_SECURITY_KEYSTORE → 节点加载 enclave 私钥不入库,权限文件签名后分发,策略默认拒绝、显式允许