Security Access Controls
Goal: Limit the topics a node can use
Tutorial level: Advanced
Time: 20 minutes
Background
Permissions are quite flexible and can be used to control many behaviors within the ROS graph.
For this tutorial, we demonstrate a policy which only allows publishing messages on the default chatter
topic.
This would prevent, for instance, remapping the topic when launching the listener or using the same security enclaves for another purpose.
In order to enforce this policy, we need to update the permissions.xml
file and re-sign it before launching the node.
This can be done by modifying the permissions file by hand, or by using XML templates.
Modify permissions.xml
Begin by making a backup of your permissions files, and open permissions.xml
for editing:
cd ~/sros2_demo/demo_keys/enclaves/talker_listener/talker
mv permissions.p7s permissions.p7s~
mv permissions.xml permissions.xml~
vi permissions.xml
We will be modifying the <allow_rule>
for <publish>
and <subscribe>
.
The topics in this XML file use the DDS naming format, not the ROS name.
Find details on mapping topic names between ROS and DDS in the Topic and Service Names design document.
Paste the following XML content into permission.xml
, save the file and exit the text editor.
This shows the chatter
and rosout
ROS topics renamed to the DDS rt/chatter
and rt/rosout
topics, respectively:
<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>
This policy allows the talker to publish on the chatter
and the rosout
topics.
It also allows includes publish and subscribe permissions needed for the talker node to manage parameters (a requirement for all nodes).
Discovery permissions remain unchanged from the original template.
Sign the policy file
This next command creates the new S/MIME signed policy file permissions.p7s
from the updated XML file permissions.xml
.
The file must be signed with the Permissions CA certificate, which requires access to the Permission CA private key.
If the private key has been protected, additional steps may be required to unlock and use it accoring to your security plan.
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
Launch the node
With the updated permissions in place, we can launch the node successfully using the same command used in prior tutorials:
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker
However, attempting to remap the chatter
topic prevents the node from launching (note that this requires the ROS_SECURITY_STRATEGY
set to Enforce
).
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker \
--remap chatter:=not_chatter
Use the templates
Security policies can quickly become confusing, so the sros2
utilities add the ability to create policies from templates.
Do this by using the sample policy file provided in the sros2
repository.
Let’s creates a policy for both the talker
and the listener
to only use the chatter
topic.
Begin by downloading the sros2
repository with the sample policy files:
git clone https://github.com/ros2/sros2.git /tmp/sros2
Then use the create_permission
verb while pointing to the sample policy to generate the XML permission files:
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
These permission files allow nodes to only publish or subscribe to the chatter
topic, and enable communications required for parameters.
In one terminal with security enabled as in previous security tutorials, run the talker
demo program:
ros2 run demo_nodes_cpp talker --ros-args -e /talker_listener/talker
In another terminal do the same with the listener
program:
ros2 run demo_nodes_py listener --ros-args -e /talker_listener/listener
At this point, your talker
and listener
nodes will be communicating securely using explicit access control lists.
However, the following attempt for the listener
node to subscribe to a topic other than chatter
will fail:
ros2 run demo_nodes_py listener --ros-args --enclave /talker_listener/listener \
--remap chatter:=not_chatter