部署指南
目标:了解将安全工件部署到生产系统中的最佳实践。
教程级别:高级
时间:20 分钟
背景
典型的部署场景通常涉及将容器化应用程序或包运送到远程系统中。
部署启用安全性的应用程序时应特别注意,要求用户考虑打包文件的敏感性。
符合`DDS 安全标准<https://www.omg.org/spec/DDS-SECURITY/1.1/About-DDS-SECURITY/>`_, ``sros2``包提供了一组实用程序,用于以高度模块化和灵活的方式在 ROS 2 环境下管理安全性。
关于如何组织不同证书、密钥和目录的基本核心指南仍然是避免危及系统安全性的关键因素。
这包括保护意识和选择在远程生产系统上部署的最少必要文件集的标准,以最大限度地减少安全风险。
先决条件
使用 compose 插件安装 docker。
请参阅 Docker 安装 和 Compose 插件 中详述的安装步骤。 * (推荐)对 ROS 2 安全设计 有基本的了解。 * (推荐)完成以前的安全教程。特别是:
一般准则
ROS 2 利用 DDS 安全扩展来确保同一区域内消息交换的安全性。 飞地内的不同签名文件和证书由“证书颁发机构 (CA) <https://en.wikipedia.org/wiki/Certificate_authority>”可信实体的私钥和证书生成。 事实上,每个飞地可以选择两个不同的 CA 来获取身份和权限。 这些 CA 工件存储在“密钥库 <https://design.ros2.org/articles/ros2_security_enclaves.html>”的“private/”和“public/”子目录中,文件夹结构如下:
keystore
├── enclaves
│ └── ...
│ └── ...
├── private
│ └── ...
└── public
└── ...
在生产系统的典型部署中创建和使用某个证书颁发机构的良好做法是:
在仅供内部使用的组织系统内创建它。
生成/修改所需的 enclave,同时牢记:
并非所有生成的 enclave 都应部署到所有目标设备。
合理的处理方式是每个应用程序都有一个 enclave,以便分离关注点。
在设置期间将
public/
和相应的enclaves/
一起发送到不同的远程生产设备。在组织中保留和保护
private/
密钥和/或认证请求。
需要注意的是,如果 private/
文件丢失,将无法再更改访问权限、添加或修改安全配置文件。
此外,还可以考虑进一步的做法:
授予
enclaves/
目录内容的只读权限。如果给出了符合 PKCS#11 的 URI 来生成 enclave 的私钥,则可以使用 硬件安全模块 (HSM) 来存储它们。
下表概述了先前将 Keystore 目录与推荐位置相关联的陈述:
Directory / Location |
Organization |
Target Device |
Material Sensitivity |
---|---|---|---|
public |
✓ |
✓ |
Low |
private |
✓ |
✕ |
High |
enclaves |
✓ |
✓ |
Medium |
构建部署场景
为了说明一个简单的部署场景,将在“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/rolling/source/Tutorials/Advanced/Security/resources/deployment_gd/Dockerfile
现在,使用以下命令构建 docker 镜像:
# Build the base image
docker build -t ros2_security/deployment_tutorial --build-arg ROS_DISTRO=rolling .
了解 Compose 文件
Compose 配置文件使用映像将容器创建为服务。 在本教程中,配置中定义了三个服务:
keystore-creator:与之前的教程类似,它在内部初始化一个新的密钥库树目录。
这将创建 enclaves/ public/ 和 private/,在 ROS 2 Security enclaves 中有更详细的说明。
keystore
目录配置为跨容器的共享卷。
listener 和 talker:在本教程中充当远程设备参与者。
所需的 Security
环境变量以及必要的密钥库文件均来自共享卷。
可以使用以下命令下载 Compose 配置 yaml 文件:
# Download the compose file
wget https://raw.githubusercontent.com/ros2/ros2_documentation/rolling/source/Tutorials/Advanced/Security/resources/deployment_gd/compose.deployment.yaml
运行示例
在同一个工作目录“~/security_gd_tutorial”中,运行:
# Start the example
docker compose -f compose.deployment.yaml up
这应该导致以下输出:
tutorial-listener-1:
Found security directory: /keystore/enclaves/talker_listener/listener
tutorial-talker-1:
Found security directory: /keystore/enclaves/talker_listener/talker
tutorial-listener-1:
Publishing: 'Hello World: <number>'
tutorial-talker-1:
I heard: [Hello World: <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。