ROS 2 Foxy Fitzroy and its Enhanced Security Monitoring

We’re pleased to welcome the newest ROS 2 release, Foxy Fitzroy. A long-term support (LTS) release, (supported for three years), Foxy runs on the latest Ubuntu LTS, the also-recently-released Ubuntu 20.04 (supported for five years, or even longer with an ESM subscription).

Putting together a distribution like Foxy is a ton of work. Open Robotics, Canonical, and other members of the ROS 2 Technical Steering Committee would never be able to pull this off without the herculean effort from our awesome community, so thank you! If you’re interested in trying out ROS 2 Foxy on your Raspberry Pi now, check out our installation video:

New in ROS 2 Foxy

A lot of development happened for Foxy, not all of which was code. The set of tutorials was revamped, and a variety of performance improvements landed. Foxy also includes our own NoDL library for defining a static communication interface for nodes, which provides a way to infer the entire communication graph and automatically secure it and detect changes (more about that in a later article, stay tuned). Furthermore, it sees the addition of REP 2006, the ROS 2 Vulnerability Disclosure Policy, providing an easy way to report security vulnerabilities across the ROS 2 ecosystem.

These are all great developments, but my favorite new feature in Foxy is enhanced security monitoring. I might be slightly biased since we’re the ones who added it, but let me share the reasons why I feel this is such an important development for ROS.

Enhanced security monitoring

What do I mean by “enhanced security monitoring”? The robotics team at Canonical approaches monitoring within the context of Situational Awareness (SA). Mica Endsley published the commonly accepted definition of Situation(al) Awareness in 1995:

Situation awareness is the perception of the elements in the environment within a volume of time and space, the comprehension of their meaning, and the projection of their status in the near future.

Canonical’s Sid Faber wrote an article about this while he was at CERT, and he relies heavily on this image introduced by Dr. Endsly that still holds true:

That “near future” projection leads to decisions and actions to influence the environment, and we’re keen on using logs to recommend actions. Angela Horneman at CERT has a useful series on Situational Awareness that breaks this down into actionable components:

  1. Know what should be
  2. Track what is
  3. Infer when “should be” and “is” do not match
  4. Do something about the difference

This type of complex tracking and analysis doesn’t typically happen on your robot. Rather, it’s offloaded to a “Security Information and Event Management (SIEM)” system like Splunk, Nagios, Sentinel, or GuardDuty. The SIEM provides continuous log monitoring, and uses several different analysis methods to identify concerning activity (i.e. infer when “should be” and “is” don’t match).

Robotics situational awareness

So what does this look like in robotics? What is Robotics SA? Well… that’s not well defined, particularly if that robot builds on top of ROS. ROS provides a decent operational log capability (assuming nodes are properly configured to write to it), but security events are dumped into the same place as everything else in a way that makes it impossible to meaningfully extract. Much like a robot is only as good as its sensors, good situational awareness depends first and foremost on perception: effective logging of activity, both for operational as well as security needs. That is exactly what we at Canonical are taking steps to fix, with a lot of the work completed for Foxy.

The DDS-Security spec includes a security logging plugin, but DDS implementations aren’t required to provide it, which means that out of the three Tier 1 DDS implementations (Fast RTPS, RTI Connext, and Cyclone DDS), only one supports it: RTI Connext. Sadly, despite it being supported in Connext, ROS 2 itself didn’t support security logging, thus this feature wasn’t available to users of ROS 2. So we added that support to ROS 2. That wasn’t quite enough though: Connext isn’t the default DDS implementation– that’s Fast RTPS. So we added the security logging plugin to Fast RTPS, and added the ability to use it in ROS 2 as well.

Using these new features together means that you, dear user, can now extract security events from your ROS 2 system, getting you a huge step closer to proper SA. It means your ROS 2 system can log when a given node is behaving in a way you didn’t expect (e.g. is trying to communicate using an unexpected topic), or when an unauthenticated node is attempting to join a secured ROS 2 graph, and so on.

How do I use security logging in ROS 2?

Assuming you’re using one of the two DDS implementations that supports security logging (RTI Connext and Fast RTPS), you first need to enable ROS 2’s security features. After that, enabling the security log is a simple matter of defining a few environment variables:

  • ROS_SECURITY_LOG_FILE: Log security events to the specified file
  • ROS_SECURITY_LOG_PUBLISH: Log security events to DDS as outlined in the DDS-Security spec
  • ROS_SECURITY_LOG_VERBOSITY: Desired verbosity of the security log (one of “DEBUG”, “INFO”, “WARN”, “ERROR”, or “FATAL”)

Those variables take effect on all the nodes run when they’re defined. If you define them for a single ros2 run invocation, they will only apply to that node. If you define them for a ros2 launch invocation, they will apply to all nodes being launched.

Let’s walk through an example. You’ll need Foxy installed– to do that, you can either follow the video above, or follow the documentation.

Example of security logging

Make sure you install at least ros-foxy-ros-base. Also install the demo nodes that we’ll use in a moment:

$ sudo apt install ros-foxy-demo-nodes-cpp

We’re going to use the SROS2 utilities to set up two different keystores (more information about this can be found in the SROS2 utilities guide):

$ mkdir ~/security_logging_demo
$ cd ~/security_logging_demo
$ ros2 security create_keystore keystore1
$ ros2 security create_keystore keystore2

Each of these keystores has a different certificate authority (CA). As a result, nodes with keys in one keystore will not be able to communicate with nodes with keys in the other keystore (since they’re signed by different CAs). Such a setup is of limited usefulness, but it’s considered a security issue, and logged as such, which is exactly what I’m trying to show here. We’ll be using the classic talker/listener example, so let’s create an identity (keypair) for the talker in one keystore, and an identity for the listener in the other:

$ ros2 security create_key keystore1 /talker_listener/listener
$ ros2 security create_key keystore2 /talker_listener/talker

At this point we have two keystores, each with one identity created, for each party in our example. Open two terminals. In the first, activate keystore1 and run the listener:

$ export ROS_SECURITY_KEYSTORE=~/security_logging_demo/keystore1
$ export ROS_SECURITY_ENABLE=true
$ export ROS_SECURITY_STRATEGY=Enforce
$ ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener

In the second terminal, activate keystore2:

$ export ROS_SECURITY_KEYSTORE=~/security_logging_demo/keystore2
$ export ROS_SECURITY_ENABLE=true
$ export ROS_SECURITY_STRATEGY=Enforce

Before we run the talker, we’ll set the environment variables to enable the security log, as well as set the verbosity to WARN:

$ export ROS_SECURITY_LOG_FILE=/tmp/ros-security.log
$ export ROS_SECURITY_LOG_VERBOSITY=WARN 

Finally, run the talker:

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

The first thing you’ll notice is that the talker appears to be working like normal, but the listener isn’t receiving anything. If you take a look at the security log file, you’ll see why:

$ cat /tmp/ros-security.log
...
[1591814520.864581] [WARNING] 1.f.f7.e3.57.29.0.0.1.0.0.0|0.0.1.c1 0 PKIDH::begin_handshake_reply : Error verifying certificate

Because the talker can’t verify the listener’s identity, the handshake fails and the listener doesn’t get any messages. If you saw this in your SIEM you would know that what “is” wasn’t matching what “should be”: there’s either a misconfiguration, or someone unauthorised is poking at your robot.

Foxy is the first ROS release where extracting such events is easy. This feature is still in the early stages of development, and it will continue to see steady improvements (for example, we’d like to get it exposed in a way that is more well-defined than setting environment variables). Please give this a try and let us know what other improvements you’d like to see!

Talk to us today

Interested in running Ubuntu Desktop in your organisation?

Newsletter signup

Select topics you’re
interested in

In submitting this form, I confirm that I have read and agree to Canonical’s Privacy Notice and Privacy Policy.

Are you building a robot on top of Ubuntu and looking for a partner? Talk to us!

Contact Us

Related posts

The State of Robotics – June 2020

ROS, Ripple and reflections – In this month’s edition of The State of Robotics, we’ll tell you about the recently discovered Ripple vulnerability, the latest...

Feeling at home in a LXD container

In this post, we will see how we can containerize our home in LXD simply managing our personal configuration files – a.k.a. dotfiles. Yeah dotfiles, named...

Installing ROS in LXD Containers

It’s the season for updates. The last few weeks have ushered in ROS 1 Noetic and ROS 2 Foxy, both of which target the recently released Ubuntu 20.04 Focal...