部署指南

目标: 了解在将安全工件部署到生产系统时的最佳实践。

教程级别: 高级

**时间:**20分钟

背景

典型的部署场景通常涉及将容器化应用程序或软件包发送到远程系统。在部署安全启用的应用程序时,需要特别注意,用户需要考虑打包文件的敏感性。

符合 DDS Security 标准sros2 软件包以高度模块化和灵活的方式提供了一套用于在 ROS 2 环境中管理安全性的实用工具。

基本的核心指南是如何组织不同的证书、密钥和目录,这仍然是避免危害系统安全的关键因素。这包括保护意识和选择最小必要文件集合以在远程生产系统上部署,以减少安全风险的标准。

先决条件

一般指南

ROS 2利用DDS安全扩展确保同一封闭环境内的消息交换的安全性。封闭环境中的不同签名文件和证书是由受信任的`证书颁发机构(Certificate Authority,CA)<https://en.wikipedia.org/wiki/Certificate_authority>`_的私钥和证书生成的。实际上,可以为每个封闭环境选择两个不同的CA来进行身份验证和权限控制。这些CA的相关文件存储在`Keystore <https://design.ros2.org/articles/ros2_security_enclaves.html>`_的``private/``和``public/``子目录中,具有以下文件夹结构:

keystore
├── enclaves
│   └── ...
│       └── ...
├── private
│   └── ...
└── public
    └── ...

对于生产系统的典型部署,使用和创建特定证书颁发机构的一个良好实践是:

  1. 将其创建在仅用于内部使用的组织系统内。

  2. 在生成/修改所需的封闭环境时要注意以下事项:

    • 并非所有生成的enclave都应该部署到所有目标设备。

    • 一个合理的方法是每个应用程序都有一个enclave,以实现关注点的分离。

  3. 在设置过程中,将``public/``与相应的``enclaves/``一起发送到不同的远程生产设备。

  4. 在组织中保留和保护``private/``密钥和/或证书请求。

需要注意的是,如果``private/``文件丢失,将无法再更改访问权限、添加或修改安全配置文件。

此外,还可以考虑采取以下进一步措施:

下表概述了之前关于密钥库目录与推荐位置的陈述:

目录 / 位置

组织

目标设备

材料敏感性

公开

私有

隔离区

中等

构建部署方案

为了演示一个简单的部署方案,将在提供的``ros:<DISTRO>``镜像之上构建一个新的Docker镜像。从该镜像开始,将创建三个容器,目标是:

  • 在本地主机的共享卷中初始化密钥库。

  • 模拟两个已部署的远程设备,以安全方式相互交互。

在这个例子中,本地主机作为组织的系统。让我们从创建一个工作空间文件夹开始:

mkdir ~/security_gd_tutorial
cd ~/security_gd_tutorial

生成 Docker 镜像

为了构建一个新的 Docker 镜像,需要一个 Dockerfile。可以使用以下命令获取本教程中提供的 Dockerfile:

# Download the Dockerfile
wget https://raw.githubusercontent.com/ros2/ros2_documentation/humble/source/Tutorials/Advanced/Security/resources/deployment_gd/Dockerfile

现在,使用以下命令构建 Docker 镜像:

# Build the base image
docker build -t ros2_security/deployment_tutorial --build-arg ROS_DISTRO=humble .

理解compose文件

一个compose配置文件会使用镜像创建容器作为服务。在本教程中,配置文件中定义了三个服务:

  • keystore-creator:与之前的教程类似,它内部初始化一个新的keystore树目录。这将创建 enclaves/public/private/ 目录,详细说明请参考 ROS 2 Security enclaveskeystore 目录被配置为容器之间的共享卷。

  • listenertalker:在本教程中充当远程设备的角色。还会从共享卷中获取所需的``Security``环境变量和必要的keystore文件。

可以通过以下命令下载compose配置的yaml文件:

# Download the compose file
wget https://raw.githubusercontent.com/ros2/ros2_documentation/humble/source/Tutorials/Advanced/Security/resources/deployment_gd/compose.deployment.yaml

运行示例:

在相同的工作目录 ~/security_gd_tutorial 下运行:

# Start the example
docker compose -f compose.deployment.yaml up

预期的输出结果如下所示:

  • 教程-监听者1: 发现安全目录: /keystore/enclaves/talker_listener/listener

  • 教程-对话者1: 发现安全目录: /keystore/enclaves/talker_listener/talker

  • 教程-监听者1: 发布: '你好世界: <number>'

  • 教程-对话者1: 我听到了: [你好世界: <number>]

检查容器

在模拟本教程的两个远程设备的容器运行时,通过打开两个不同的终端并输入以下命令来连接到每个容器:

# Terminal 1
docker exec -it tutorial-listener-1 bash
cd keystore
tree

# Terminal 2
docker exec -it tutorial-talker-1 bash
cd keystore
tree

应该获得类似于下面所示的输出:

# Terminal 1
keystore
 ├── enclaves
 │   ├── governance.p7s
 │   ├── governance.xml
 │   └── talker_listener
 │       └── listener
 │           ├── cert.pem
 │           ├── governance.p7s
 │           ├── identity_ca.cert.pem
 │           ├── key.pem
 │           ├── permissions_ca.cert.pem
 │           ├── permissions.p7s
 │           └── permissions.xml
 └── public
     ├── ca.cert.pem
     ├── identity_ca.cert.pem
     └── permissions_ca.cert.pem

# Terminal 2
keystore
 ├── enclaves
 │   ├── governance.p7s
 │   ├── governance.xml
 │   └── talker_listener
 │       └── talker
 │           ├── cert.pem
 │           ├── governance.p7s
 │           ├── identity_ca.cert.pem
 │           ├── key.pem
 │           ├── permissions_ca.cert.pem
 │           ├── permissions.p7s
 │           └── permissions.xml
 └── public
     ├── ca.cert.pem
     ├── identity_ca.cert.pem
     └── permissions_ca.cert.pem

请注意:

  • private/ 文件夹未被移动,而是留在本地主机(组织)中。

  • 每个部署设备都包含其所需的最小隔离环境,以供其应用程序使用。

注解

为简单起见,同一证书颁发机构(CA)在此隔离环境中同时用于身份和权限。