11. ROS 2与DDS-Security的集成

机器人技术充满了各种实验:评估不同的硬件和软件,推进可行的技术,剔除不可行的技术。ROS设计非常灵活以开展这些实验;以允许现有组件轻松与新组件组合或切换为其他组件。在ROS 1中,这种灵活性高于一切,但却以牺牲安全性为代价。ROS 2由于是在DDS之上设计的,既能保留这种灵活性,同时也能通过合理利用DDS-Security规范获得安全能力。本文介绍了ROS 2是如何与DDS-Security进行集成的。

作者:凯尔·法扎里(Kyle Fazzari)

撰写日期:2019-07

最后修改时间:2020-07

11.1 DDS-Security概述

DDS-Security规范DDS规范的基础上进行了扩展,通过定义服务插件接口SPI(Service Plugin Interface)架构、一系列SPI内置实现以及由SPI强制执行的安全模型来添加增强型安全功能。具体来说,DDS-Security定义了以下五个SPI:

 身份验证(Authentication):对给定域参与者的身份进行验证。

 访问控制(Access control):对经过身份验证的域参与者能够执行的DDS相关操作强制实行各种限制。

 加密(Cryptographic):对所有必需的加密、签名和散列操作进行处理。

 日志记录(Logging):提供审计DDS-Security相关事件的能力。

 数据标记(Data tagging):提供向数据样本添加标记的能力。

ROS 2的安全功能目前仅使用了前三个SPI。这是由于为符合DDS-Security规范,既不需要日志记录也不需要数据标记(参见该规范2.3节),因此并非所有DDS实现都支持后两个SPI。下面来深入研究一下前三个插件。

11.1.1 身份验证(Authentication)

身份验证插件(参见DDS-Security规范8.3节)是整个SPI架构的核心,因为身份验证插件提供了经确认的身份这一概念,没有经确认的身份就不可能进一步执行其它安全操作(例如,如果无法安全地确定其具体身份,则很难确保某个给定的ROS身份只会访问某些特定话题)。

SPI架构允许有多种潜在的身份验证方案,但ROS 2使用的是内置身份验证插件(称为“DDS:Auth:PKI-DH”,请参阅DDS-Security规范9.3节),该插件使用经过验证的公钥基础设施PKI(Public Key Infrastructure)。该插件需要每个域参与者的一个公钥和一个私钥,以及将该参与者的公钥绑定到某个特定名称的x.509证书。每个x.509证书都必须由该插件配置为信任的某个特定证书颁发机构CA(Certificate Authority)签名(或者具有一个签名链)。

使用该内置插件而不是其他任何插件的理由有两个:

1. 这是DDS-Security规范中详细描述的唯一方法。

2. 所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2的安全功能可以以最小工作量跨不同DDS供应商正常工作。

11.1.2 访问控制(Access control)

访问控制插件(参见DDS-Security规范8.4节)处理某个给定域参与者DDS相关功能限制的定义和实施。例如,该插件可以允许用户将某个特定参与者限制在某个特定的DDS域中,或者只允许该参与者读取或写入某些特定的DDS话题,等等。

同样地,SPI架构允许在插件如何完成此任务方面具有一定的灵活性,但ROS 2使用的又是内置的访问控制插件(称为“DDS:Access:Permission”,参见DDS-Security规范9.4节),该插件也使用PKI。该插件需要每个域参与者的下面这两个文件:

 治理(Governance)文件:一个签名的XML文档,用于指定该域应如何保障安全。

 权限(Permissions)文件:一个签名的、包含域参与者各项权限的XML文档,该文件会被绑定至身份验证插件定义的参与者名称(这是通过x.509证书完成的,正如前面所讨论的那样)。

这两个文件都必须由该插件配置为信任的证书颁发机构CA签名。该CA可能是身份验证插件信任的同一个CA,但这并不是必需的。

使用访问控制内置插件而不是其他任何插件的理由与身份验证插件的完全相同:

● 这是规范中详细描述的唯一方法。

● 所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2安全功能可以以最小的工作量跨不同供应商正常工作。

11.1.3 加密(Cryptographic)

加密插件(参见DDS-Security规范8.5节)是处理所有与加密相关操作的地方,包括:加密、解密、签名、散列等。身份验证访问控制插件都会利用加密插件的功能以便进行签名验证等。加密DDS话题通信的功能也位于加密插件中。

虽然SPI架构又一次允许加密插件有多种可能性,但ROS 2使用的又是内置的加密插件(称为“DDS:Crypto:AES-GCM-GMAC”,请参阅DDS-Security规范9.5节),该内置插件可以提供经过身份验证的、使用高级加密标准AES(Advanced Encryption Standard)Galois计数器模式GCM(Galois Counter Mode)即AES-GCM加密算法的加密。

使用该内置插件而不是其他插件的理由与其他两个插件相同:

● 这是规范中详细描述的唯一方法。

● 所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2安全功能可以以最小的工作量跨不同供应商正常工作。

11.2 DDS-Security与ROS 2的集成:SROS 2

现在已经对DDS中如何支持安全功能建立了一些共同的理解,下面来讨论如何在ROS 2中公开这种支持功能。默认情况下,ROS 2中并没有启用DDS的任何安全功能。ROS 2中用于启用DDS安全功能的特性和工具集统称为“安全(Secure) ROS 2”,简写即为SROS 2。

11.2.1 ROS客户端库(RCL)中的安全功能

大多数面向用户的SROS 2运行时支持都包含在ROS客户端库中。一旦满足其要求,ROS客户端库(RCL)就会为每个受支持的DDS实现配置该中间件支持。RCL中包括以下 SROS 2功能:

● 对每个域参与者安全文件的支持。

● 同时对宽松和严格的安全措施进行支持。

● 对用于所有SROS 2功能的一个主“开/关”开关功能的支持。

下面来依次讨论这三个安全功能。

(1)对每个域参与者安全文件的支持

如前所述,DDS-Security插件需要每个域参与者的一系列安全文件(如密钥、治理文件和权限文件等)。域参与者会映射到ROS 2的进程内环境(context)中,因此每个进程都需要一组这些文件。RCL支持以两种不同的方式指向包含安全文件的目录:

● 所有安全文件的目录树。

● 手动指定。

下面来进一步深入研究这两种方式。

1)所有安全文件的目录树

RCL支持在预留的enclaves子文件夹内的某个目录中查找安全文件,在根密钥库内,该目录对应于每个安全飞地(enclave)的完全合格路径。例如, /front/camera飞地的目录结构如下图所示:

每个飞地实例目录中预期的文件集为:

● identity_ca.cert.pem:身份验证插件信任的CA(“身份”CA)的x.509证书。

● cert.pem:本飞地实例的x.509证书(由身份CA签名)。

● key.pem:本飞地实例的私钥。

● permission_ca.cert.pem:访问控制插件信任的CA(“权限”CA) 的x.509证书。

● government.p7s:用于向访问控制插件指定应如何保护域安全的XML文档(由权限CA签名),即治理文件。

● permission.p7s:用于向访问控制插件指定本特定飞地实例权限的XML 文档(也由权限 CA 签名),即权限文件。

这可以通过将ROS_SECURITY_KEYSTORE环境变量设置为指向密钥库目录树的根目录路径来完成,然后使用--ros-args运行时参数-e或者--enclave来指定该飞地的路径,例如:

export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
ros2 run <package> <executable> --ros-args --enclave="/front/camera"

2)手动指定

RCL还支持为需要使用覆盖环境变量启动的进程指定飞地路径。这可以通过将ROS_SECURITY_ENCLAVE_OVERRIDE环境变量设置为密钥库中的备用飞地路径来完成。请注意,这种设置方式的优先权要高于使用--enclave参数的ROS_SECURITY_KEYSTORE环境变量设置方式。

请注意,下面这两个示例加载的飞地路径与前面演示中的飞地路径相同(笔者注:第二个示例中虽然使用--enclave参数指定了不同的飞地实例/spam,但由于ROS_SECURITY_ENCLAVE_OVERRIDE环境变量会覆盖该参数,因此加载的还是/front/camera飞地实例):

export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable>

export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable> --ros-args --enclave="/spam"

(2)同时对宽松和严格的安全措施进行支持

启用了安全功能的参与者将不会与未启用安全功能的参与者进行通信,但是如果有人尝试启动一个带有密钥/权限/等文件的不可识别飞地的参与者,RCL应该怎么办?RCL可以有以下两个选择:

● 宽容模式(Permissive mode):会尝试查找各个安全文件,如果找不到这些安全文件,则会在不启用任何安全功能的情况下启动该参与者。这是RCL的默认行为。

● 严格模式(Strict mode):会尝试查找各个安全文件,如果找不到这些安全文件,则无法运行该参与者。

指定期望模式的方法为:通过将ROS_SECURITY_STRATEGY环境变量设置为“Enforce”(区分大小写)来指定严格模式,而将该环境变量设置为任何其他值来指定宽容模式。

(3)对用于所有SROS 2功能的一个主“开/关”开关功能的支持

除了前面刚讨论的两项受支持的功能之外,RCL还支持安全功能的主关闭以便于实验。如果关闭(默认选项),则不会启用上述任何安全功能。

为了启用SROS 2,请将ROS_SECURITY_ENABLE环境变量设置为“true”(区分大小写)。若要禁用SROS 2,则请将该环境变量设置为任何其他值。

11.2.2 SROS 2 命令行界面(CLI)中的安全功能

在RCL中对ROS 2系统进行安全配置涉及到许多新技术(如PKI、DDS治理文件和权限文件以及它们的语法等)。如果用户熟悉这些技术,则上述信息应该是正确配置SROS 2所必需的全部信息。但是,SROS 2命令行界面(CLI )应该包含一个工具ros2 security来帮助那些不想完全由自己来设置ROS 2安全功能的人,该工具应包括以下几项功能:

● 创建身份CA和权限CA。

● 创建包含所有安全文件的目录树。

● 为某个给定的安全飞地创建一个新身份,生成密钥对并使用身份CA签署其x.509证书。

● 创建一个默认情况下会加密所有DDS数据流的治理文件。

● 支持以熟悉的ROS术语指定飞地权限,然后自动将该飞地权限转换为底层DDS权限。

● 支持从正在运行的ROS系统中自动发现所需的各项权限。

*英语原文网址:design.ros2.org/article...