micro-ROS/micro-ROS-Agent

Variable ROS_LOCALHOST_ONLY (to avoid broadcasting) does not work with micro-ros client/agent

anaelle-sw opened this issue · 11 comments

Hello! We would like to not broadcast the ROS topics on our WiFi network. We can't find out how to do so, while running micro-ROS agent and client.

System:

  • Ubuntu 20.04, ROS2 Foxy
  • Teensy 3.5

Steps to follow:

In order to avoid to broadcast the ROS topics we set up this environment variable on our system:
export ROS_LOCALHOST_ONLY=1.
It works great for our ROS nodes running on this system, the topics are not broadcasted.

Issues:

  • On the system, the communication between ROS and the micro-ROS-agent is not established
  • The micro-ROS-client node running on the board is still broadcasting on the network

Question:

How can we avoid broadcasting ROS topics on our WiFi network, but still normally use micro-ROS?

Thanks for helping!

Hello @anaelle-sw, I'm not sure to have understood this well:

  • You want to avoid micro-ROS topic being published to the ROS 2 dataspace?
  • Does this mean that you only want micro-ROS nodes to exchange data between them?
  • Why do you want this behavior because of network load? Have you thought about changing the domain id for the micro-ROS nodes?

Hi @pablogs9 !

Sorry it wasn't clear. Let me precise a bit more our use case:

On our system, we have a computer on which run ROS nodes. Some of theses nodes need to receive/send data to a Teensy board. On this board, we run a single micro-ROS-arduino node, and on the computer we run a micro-ROS-agent. Communication between the board and the agent is done via serial communication. Everything used to work fine this way.

The problem is that the ROS nodes running on the computer, as well as the micro-ROS-arduino node running on the Teensy board, are broadcasting on the WiFi network that the computer has access to. The result is that we can access the ROS nodes running on a system from another system. But we don't want our systems to be able to communicate between them. So, more than specifying a domain ID, we really need to make secured our system and avoid any ROS and micro-ROS-arduino node been broadcasted on a network.

The solution we found to secure this is to set up this environment variable on our system's computer: export ROS_LOCALHOST_ONLY=1. Thanks to it, the ROS nodes running on the computer are not broadcasted anymore on the WiFi network. But two problems linked to micro-ROS happened then:

  • The micro-ROS-arduino node is still broadcasting on the network, which is really unwanted. How can we prevent this?
  • The ROS nodes cannot receive/send data to the board anymore. How can we fix this?

So, to answer your questions:

  • We do want to have micro-ROS topic published to the ROS 2 dataspace
  • We only have one micro-ROS node per system, and we don't want systems to be able to access to each other micro-ROS nodes.
  • We don't want node broadcasting to have secured systems, we don't think changing the domain id would be enough securised.

The first solution that cames to my mind is:

I have not tested this, but it should work.

Maybe we should discuss what localhost means in micro-ROS because it can be:

  • communications inside the same MCU
  • communications inside the same Agent
  • communications in the localhost where the agent is <- Wyca case.

Thoughs @jamoralp?

For reference, it used to be an issue on standard ROS2 nodes too: https://answers.ros.org/question/333687/restrict-ros-2-to-localhost/
That issue was solved by a behavior based on the ROS_LOCALHOST_ONLY env variable since Eloquent:

* communications in the localhost where the agent is <- Wyca case.

It would be nice of this behavior would be enabled by simply reading the ROS_LOCALHOST_ONLY env variable of the localhost where the agent is

Hi @pablogs9!

For now, we are using distinct ROS_DOMAIN_IDs on all our systems. To do so, we set the environment variable ROS_DOMAIN_ID, and we create the node running on the board this way:

  node = rcl_get_zero_initialized_node();
  rcl_node_options_t node_ops = rcl_node_get_default_options();
  node_ops.domain_id = 56;
  RCCHECK(rclc_node_init_with_options(&node, "micro_ros_teensy_node", "", &support, &node_ops));

But using this, if system A includes a Teensy board A, then we are still able to catch the node running on the board A by calling ros2 node list from system B, even with both systems having different domain ID's. Is this normal? I can precise that the ROS nodes running on system A (other than the one of the board) are not visible from system B.

About the reference file solution, as @doisyg said, we would enjoy a more easy way to not allow network broadcasting. For now, we will keep the ROS_DOMAIN_ID solution, but this is not the safer way, we would rather cut off any network broadcasting by using ROS_LOCALHOST_ONLY, so this is temporary only.

Regarding the domain ID problem, maybe @jamoralp can tell us something about how the node concept is managed in ROS 2 graph. I'm pretty sure that two DDS participants with different domain ID are not visible for each other, but ROS 2 nodes are not exactly DDS participants... Let me do some tests.

Regarding the localhost isolation, we are working right now on version 2.0.0 of XRCE-DDS, when we finish maybe we can design some solution for this. I'll keep this open to remember it.

Hello @anaelle-sw we have been testing this and we found a XML profile that works for your purposes:

<dds>
	<profiles>
		<transport_descriptors>
			<transport_descriptor>
				<transport_id>udp_localhost</transport_id>
				<type>UDPv4</type>
				<interfaceWhiteList>
					<address>127.0.0.1</address>
				</interfaceWhiteList>
			</transport_descriptor>
		</transport_descriptors>
	</profiles>
	<participant>
		<rtps>
			<name>default_xrce_participant</name>
			<useBuiltinTransports>false</useBuiltinTransports>
			<userTransports>
				<transport_id>udp_localhost</transport_id>
			</userTransports>
		</rtps>
	</participant>
</dds>

Using this, the micro-ROS participants created in an Agent will only be able to talk "ROS 2" using localhost interface, so ROS 2 nodes o other agents in the same machine will be in communication but other computers in the same LAN will not receive anything.

You can set this profile using this guide: https://micro-ros.github.io/docs/tutorials/core/create_dds_entities_by_ref/

I'm going to close since it is almost resolved. But if you try it and it does not work please reopen this same issue.

Thanks!!

Hi @pablogs9,

The link mentioned in your previous reply seems to be broken. Is there any example of this in the updated docs?

Hi. I have the same problem as @anaelle-sw had and I didn't succeed to solve it using the ref file as @pablogs9 suggested.
I've tried the suggested steps to use .ref file but it didn't work - the broadcast still happened.

I'm using Ubuntu 20.4 and ROS2 humble (compiled from source) inside docker container the runs on Jetson Xavier nx.
in our ROS2 system (that we are trying to integrate micro-ros to) we're using cyclone dds.

Thanks!