设置访问控制

**目标:**限制节点可以使用的主题。

教程级别: 高级

**时间:**20分钟

背景

权限非常灵活,可用于控制ROS图中的许多行为。

对于本教程,我们演示了一种只允许在默认“chatter”主题上发布消息的策略。这将防止例如在启动监听器时重新映射主题或将相同的安全隔离用于其他目的。

为了执行此策略,在启动节点之前,我们需要更新“permissions.xml”文件并重新签名。可以通过手动修改权限文件或使用XML模板来完成此操作。

修改“permissions.xml”

首先,备份您的权限文件,并打开“permissions.xml”以进行编辑:

cd ~/sros2_demo/demo_keys/enclaves/talker_listener/talker
mv permissions.p7s permissions.p7s~
mv permissions.xml permissions.xml~
vi permissions.xml

我们将修改``<allow_rule>``中的``<publish>``和``<subscribe>``。此XML文件中的主题使用DDS命名格式,而不是ROS名称。有关在ROS和DDS之间映射主题名称的详细信息,请参阅`Topic and Service Names设计文档 <https://design.ros2.org/articles/topic_and_service_names.html#mapping-of-ros-2-topic-and-service-names-to-dds-concepts>`_。

将以下XML内容粘贴到``permission.xml``中,保存文件并退出文本编辑器。这将显示``chatter``和``rosout`` ROS主题分别重命名为DDS的``rt/chatter``和``rt/rosout``主题:

<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.omg.org/spec/DDS-SECURITY/20170901/omg_shared_ca_permissions.xsd">
  <permissions>
    <grant name="/talker_listener/talker">
      <subject_name>CN=/talker_listener/talker</subject_name>
      <validity>
        <not_before>2021-06-01T16:57:53</not_before>
        <not_after>2031-05-31T16:57:53</not_after>
      </validity>
      <allow_rule>
        <domains>
          <id>0</id>
        </domains>
        <publish>
          <topics>
            <topic>rt/chatter</topic>
            <topic>rt/rosout</topic>
            <topic>rt/parameter_events</topic>
            <topic>*/talker/*</topic>
          </topics>
        </publish>
        <subscribe>
          <topics>
            <topic>rt/parameter_events</topic>
            <topic>*/talker/*</topic>
          </topics>
        </subscribe>
      </allow_rule>
      <allow_rule>
        <domains>
          <id>0</id>
        </domains>
        <publish>
          <topics>
            <topic>ros_discovery_info</topic>
          </topics>
        </publish>
        <subscribe>
          <topics>
            <topic>ros_discovery_info</topic>
          </topics>
        </subscribe>
      </allow_rule>
      <default>DENY</default>
    </grant>
  </permissions>
</dds>

此策略允许talker在``chatter``和``rosout``主题上进行发布。它还包括talker节点管理参数所需的发布和订阅权限(所有节点的要求)。与原始模板相比,发现权限保持不变。

签署策略文件

下一个命令从更新的XML文件 permissions.xml 创建新的S/MIME签名策略文件 permissions.p7s。该文件必须使用权限CA证书进行签名,这需要访问权限CA私钥。如果私钥已经受保护,根据您的安全计划可能需要额外的步骤来解锁和使用它。

openssl smime -sign -text -in permissions.xml -out permissions.p7s \
  --signer permissions_ca.cert.pem \
  -inkey ~/sros2_demo/demo_keys/private/permissions_ca.key.pem

启动节点

在更新的权限设置生效后,我们可以使用之前教程中相同的命令成功启动节点:

ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker

但是,尝试重新映射 chatter 主题将阻止节点启动(请注意,这需要将 ROS_SECURITY_STRATEGY 设置为 Enforce)。

ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker \
  --remap chatter:=not_chatter

使用模板

安全策略很容易变得混乱,因此``sros2``工具添加了从模板创建策略的功能。可以通过使用``sros2``仓库中提供的`样例策略文件<https://github.com/ros2/sros2/blob/humble/sros2/test/policies/sample.policy.xml#L1>`_来实现。让我们为``talker``和``listener``创建一个策略,限制它们仅使用``chatter``主题。

首先下载包含样例策略文件的``sros2``仓库:

git clone https://github.com/ros2/sros2.git /tmp/sros2

然后使用``create_permission``命令,并指向样例策略文件以生成XML权限文件:

ros2 security create_permission demo_keystore \
  /talker_listener/talker \
  /tmp/sros2/sros2/test/policies/sample.policy.xml
ros2 security create_permission demo_keystore \
  /talker_listener/listener \
  /tmp/sros2/sros2/test/policies/sample.policy.xml

这些权限文件允许节点仅发布或订阅``chatter``主题,并启用参数所需的通信。

在一个启用了安全性的终端中,运行之前安全教程中的``talker``演示程序:

ros2 run demo_nodes_cpp talker --ros-args -e /talker_listener/talker

在另一个终端中,使用``listener``程序执行相同的操作:

ros2 run demo_nodes_py listener --ros-args -e /talker_listener/listener

此时,您的``talker``和``listener``节点将使用显式访问控制列表进行安全通信。然而,``listener``节点尝试订阅``chatter``以外的主题将失败:

ros2 run demo_nodes_py listener --ros-args --enclave /talker_listener/listener \
  --remap chatter:=not_chatter