自学内容网 自学内容网

【ROS2】高级:安全-设置访问控制

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

 教程级别:高级

 时间:20 分钟

 内容

  •  背景

    •  修改 permissions.xml

    • 签署策略文件

    •  启动节点

    •  使用模板

 背景

在继续之前,请确保您已完成设置安全教程。

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

在本教程中,我们演示了一项仅允许在默认 chatter 主题上发布消息的策略。这将防止,例如,在启动侦听器时重新映射主题或将相同的安全飞地用于其他目的。

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

 修改 permissions.xml 

首先备份您的权限文件,然后打开 permissions.xml 进行编辑:

cd ~/sros2_demo/demo_keystore/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 之间映射主题名称的详细信息,请参阅主题和服务名称设计文档。

将以下 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">
  <!-- 定义 DDS 安全配置文件,并指定 XML schema 的位置 -->
  <permissions>
    <!-- 权限定义的开始 -->
    <grant name="/talker_listener/talker">
      <!-- 定义一个权限授予,命名为 "/talker_listener/talker" -->
      <subject_name>CN=/talker_listener/talker</subject_name>
      <!-- 指定主体名称,即被授予权限的实体,CN 是通用名称 -->
      <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>
          <!-- 定义域 ID 为 0 -->
        </domains>
        <publish>
          <!-- 定义发布权限 -->
          <topics>
            <topic>rt/chatter</topic>
            <!-- 允许发布 rt/chatter 主题 -->
            <topic>rt/rosout</topic>
            <!-- 允许发布 rt/rosout 主题 -->
            <topic>rt/parameter_events</topic>
            <!-- 允许发布 rt/parameter_events 主题 -->
            <topic>*/talker/*</topic>
            <!-- 允许发布匹配 */talker/* 的主题 -->
          </topics>
        </publish>
        <subscribe>
          <!-- 定义订阅权限 -->
          <topics>
            <topic>rt/parameter_events</topic>
            <!-- 允许订阅 rt/parameter_events 主题 -->
            <topic>*/talker/*</topic>
            <!-- 允许订阅匹配 */talker/* 的主题 -->
          </topics>
        </subscribe>
      </allow_rule>
      <!-- 第一个允许规则的结束 -->
      <allow_rule>
        <!-- 第二个允许规则的开始 -->
        <domains>
          <id>0</id>
          <!-- 定义域 ID 为 0 -->
        </domains>
        <publish>
          <!-- 定义发布权限 -->
          <topics>
            <topic>ros_discovery_info</topic>
            <!-- 允许发布 ros_discovery_info 主题 -->
          </topics>
        </publish>
        <subscribe>
          <!-- 定义订阅权限 -->
          <topics>
            <topic>ros_discovery_info</topic>
            <!-- 允许订阅 ros_discovery_info 主题 -->
          </topics>
        </subscribe>
      </allow_rule>
      <!-- 第二个允许规则的结束 -->
      <default>DENY</default>
      <!-- 默认情况下拒绝所有未明确允许的操作 -->
    </grant>
    <!-- 权限授予的结束 -->
  </permissions>
  <!-- 权限定义的结束 -->
</dds>
<!-- DDS 安全配置文件的结束 -->

此策略允许 talker 在 chatter 和 rosout 主题上发布。它还包括讲话者节点管理参数(rt/parameter_events)所需的发布和订阅权限(所有节点的要求)。发现(ros_discovery_info)权限保持原始模板不变。

签署策略文件

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

cxy@cxy-Ubuntu2404:~/sros2_demo/demo_keystore/enclaves/talker_listener/listener$ openssl smime -sign -text -in permissions.xml -out permissions.p7s \
  --signer permissions_ca.cert.pem \
  -inkey ~/sros2_demo/demo_keystore/private/permissions_ca.key.pem

启动节点

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

export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker

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

export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker \
  --remap chatter:=not_chatter

18b26a3d821d471bbf8f0022d321fd4e.png

使用模板

安全策略很快就会变得混乱,因此 sros2 实用程序增加了从模板创建策略的功能。通过使用 sros2 存储库中提供的示例策略文件来执行此操作。让我们为 talker 和 listener 创建一个策略,仅使用 chatter 主题。

首先下载包含示例策略文件的 sros2 存储库:

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

fdbb97e4ec4b57c5697627e256e8e6a1.png

cxy@cxy-Ubuntu2404:~$ tree /tmp/sros2
/tmp/sros2
├── codecov.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── sros2
│   ├── CHANGELOG.rst
│   ├── package.xml
│   ├── pytest.ini
│   ├── resource
│   │   └── sros2
│   ├── setup.py
│   ├── sros2
│   │   ├── api
│   │   │   ├── _artifact_generation.py
│   │   │   ├── __init__.py
│   │   │   └── _policy.py
│   │   ├── command
│   │   │   ├── __init__.py
│   │   │   └── security.py
│   │   ├── errors.py
│   │   ├── __init__.py
│   │   ├── keystore
│   │   │   ├── _enclave.py
│   │   │   ├── __init__.py
│   │   │   ├── _keystore.py
│   │   │   └── _permission.py
│   │   ├── policy
│   │   │   ├── defaults
│   │   │   │   ├── dds
│   │   │   │   │   ├── governance.xml
│   │   │   │   │   └── __init__.py
│   │   │   │   ├── __init__.py
│   │   │   │   └── policy.xml
│   │   │   ├── __init__.py
│   │   │   ├── schemas
│   │   │   │   ├── dds
│   │   │   │   │   ├── governance.xsd
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   └── permissions.xsd
│   │   │   │   ├── __init__.py
│   │   │   │   └── policy.xsd
│   │   │   └── templates
│   │   │       ├── dds
│   │   │       │   ├── __init__.py
│   │   │       │   └── permissions.xsl
│   │   │       ├── __init__.py
│   │   │       └── policy.xsl
│   │   ├── _utilities.py
│   │   └── verb
│   │       ├── create_enclave.py
│   │       ├── create_keystore.py
│   │       ├── create_permission.py
│   │       ├── generate_artifacts.py
│   │       ├── generate_policy.py
│   │       ├── __init__.py
│   │       └── list_enclaves.py
│   ├── test
│   │   ├── conftest.py
│   │   ├── policies
│   │   │   ├── add_two_ints.policy.xml
│   │   │   ├── common
│   │   │   │   ├── lifecycle_node.xml
│   │   │   │   ├── node
│   │   │   │   │   ├── logging.xml
│   │   │   │   │   ├── parameters.xml
│   │   │   │   │   ├── time.xml
│   │   │   │   │   └── types.xml
│   │   │   │   └── node.xml
│   │   │   ├── invalid_policy_missing_topics_tag.xml
│   │   │   ├── minimal_action.policy.xml
│   │   │   ├── permissions
│   │   │   │   ├── add_two_ints
│   │   │   │   │   └── permissions.xml
│   │   │   │   ├── minimal_action
│   │   │   │   │   └── permissions.xml
│   │   │   │   ├── sample
│   │   │   │   │   └── permissions.xml
│   │   │   │   ├── single_context
│   │   │   │   │   └── permissions.xml
│   │   │   │   └── talker_listener
│   │   │   │       └── permissions.xml
│   │   │   ├── policy_to_permissions.py
│   │   │   ├── sample.policy.xml
│   │   │   ├── single_context.policy.xml
│   │   │   └── talker_listener.policy.xml
│   │   ├── sros2
│   │   │   ├── commands
│   │   │   │   └── security
│   │   │   │       └── verbs
│   │   │   │           ├── fixtures
│   │   │   │           │   ├── client_service_node.py
│   │   │   │           │   └── pub_sub_node.py
│   │   │   │           ├── test_create_enclave.py
│   │   │   │           ├── test_create_keystore.py
│   │   │   │           ├── test_create_permission.py
│   │   │   │           ├── test_generate_artifacts.py
│   │   │   │           ├── test_generate_policy_no_nodes.py
│   │   │   │           ├── test_generate_policy.py
│   │   │   │           ├── test_list_enclaves.py
│   │   │   │           ├── test_no_verb.py
│   │   │   │           └── utilities
│   │   │   │               ├── __init__.py
│   │   │   │               └── sros2_cli_test_case.py
│   │   │   ├── keystore
│   │   │   │   └── test_enclave.py
│   │   │   └── test_utilities.py
│   │   ├── test_copyright.py
│   │   ├── test_flake8.py
│   │   ├── test_mypy.py
│   │   ├── test_pep257.py
│   │   └── test_policy_to_permissions.py
│   └── xml_cache
│       ├── README.md
│       ├── xhtml-cache.xml
│       └── xml.xsd
├── sros2_cmake
│   ├── CHANGELOG.rst
│   ├── cmake
│   │   └── sros2_generate_artifacts.cmake
│   ├── CMakeLists.txt
│   ├── package.xml
│   ├── README.md
│   └── sros2_cmake-extras.cmake
├── SROS2_Linux.md
├── SROS2_MacOS.md
└── SROS2_Windows.md


35 directories, 92 files

然后使用 create_permission 动词指向示例策略以生成 XML 权限文件:

89dc90d08bbfe463fb2ff0306658e5b5.png

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 主题,并启用参数所需的通信。

cxy@cxy-Ubuntu2404:~/sros2_demo$ ros2 security create_permission demo_keystore \ 
  /talker_listener/talker \
  /tmp/sros2/sros2/test/policies/sample.policy.xml
cxy@cxy-Ubuntu2404:~/sros2_demo$ ros2 security create_permission demo_keystore \ 
  /talker_listener/listener \
  /tmp/sros2/sros2/test/policies/sample.policy.xml

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

export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce


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

在另一个终端中对 listener 程序执行相同的操作:

export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce


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

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

15e598ac53fc8146c31000d76b9e5316.png

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

e953748c1f3ff93753df44f019f6fcf8.png

ee8469c6592517ebce52708d52452678.png


原文地址:https://blog.csdn.net/cxyhjl/article/details/140600794

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!