检查网络流量

目标: 捕获并检查原始的ROS 2网络流量。

教程级别: 高级

**时间:**20分钟

背景

ROS 2通信安全关乎保护节点之间的通信。之前的教程启用了安全性,但是如何**真正**判断流量是否被加密呢?在本教程中,我们将捕获实时网络流量,以展示加密和未加密流量之间的区别。

注解

rmw_fastrtps_cpp 默认使用 共享内存传输 来提高在传输层上的性能,当端点位于同一主机系统上时。仍然应用了安全隔离,并且数据将被加密。然而,由于数据不会出现在网络接口上,您无法捕获实时的网络流量。如果您正在使用 rmw_fastrtps_cpp,您需要在发布者和订阅者之间通过本教程进行操作,并使用不同的主机系统,或者使用 启用UDP传输如何设置Fast-DDS XML配置 来禁用共享内存传输。

运行演示

安装 tcpdump

在新的终端窗口中开始安装 tcpdump,它是一个用于捕获和显示网络流量的命令行工具。尽管本教程描述了 tcpdump 命令,你也可以使用类似的图形工具 Wireshark 来捕获和分析流量。

sudo apt update
sudo apt install tcpdump

通过多个 ssh 会话在单台机器上运行以下命令。

启动 talker 和 listener。

在各自的终端中重新启动讲话者和侦听者。安全环境变量未设置,因此这些会话未启用安全性。

# Disable ROS Security for both terminals
unset ROS_SECURITY_ENABLE

# In terminal 1:
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker

# In terminal 2:
ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener

显示未加密的发现数据包。

在运行讲话者和侦听者的同时,打开另一个终端并启动“tcpdump”以查看网络流量。由于读取原始网络流量是特权操作,因此您需要使用“sudo”。

下面的命令使用“-X”选项打印数据包内容,使用“-i”选项在任何接口上监听数据包,并仅捕获“UDP <https://en.wikipedia.org/wiki/User_Datagram_Protocol>`_端口7400的流量。

sudo tcpdump -X -i any udp port 7400

您应该看到如下的数据包:

20:18:04.400770 IP 8_xterm.46392 > 239.255.0.1.7400: UDP, length 252
  0x0000:  4500 0118 d48b 4000 0111 7399 c0a8 8007  E.....@...s.....
  0x0010:  efff 0001 b538 1ce8 0104 31c6 5254 5053  .....8....1.RTPS
  ...
  0x00c0:  5800 0400 3f0c 3f0c 6200 1c00 1800 0000  X...?.?.b.......
  0x00d0:  2f74 616c 6b65 725f 6c69 7374 656e 6572  /talker_listener
  0x00e0:  2f74 616c 6b65 7200 2c00 2800 2100 0000  /talker.,.(.!...
  0x00f0:  656e 636c 6176 653d 2f74 616c 6b65 725f  enclave=/talker_
  0x0100:  6c69 7374 656e 6572 2f74 616c 6b65 723b  listener/talker;
  0x0110:  0000 0000 0100 0000                      ........

这是一个发现数据报文,表示发话者正在寻找订阅者。正如您所见,节点名称(/talker_listener/talker)和 enclave(也是 /talker_listener/talker)以明文形式传递。您还应该看到类似的发现数据报文来自 listener 节点。一些典型发现数据包的其他特征包括:

  • 目标地址为 239.255.0.1,这是一个组播(multicast)IP 地址;ROS 2 默认使用组播流量进行发现。

  • UDP 7400 是目标端口,根据 DDS-RTPS 规范 的要求。

  • 数据包中包含"RTPS"标记,如DDS-RTPS规范所定义。

显示未加密的数据包

使用``tcpdump``来捕获非发现性的RTPS数据包,通过过滤UDP端口大于7400的数据包:

sudo tcpdump -i any -X udp portrange 7401-7500

你会看到几种不同类型的数据包,但要注意像下面这样的明显是从一个讲话者发送给一个听众的数据:

20:49:17.927303 IP localhost.46392 > localhost.7415: UDP, length 84
  0x0000:  4500 0070 5b53 4000 4011 e127 7f00 0001  E..p[S@.@..'....
  0x0010:  7f00 0001 b538 1cf7 005c fe6f 5254 5053  .....8...\.oRTPS
  0x0020:  0203 010f 010f 4874 e752 0000 0100 0000  ......Ht.R......
  0x0030:  0901 0800 cdee b760 5bf3 5aed 1505 3000  .......`[.Z...0.
  0x0040:  0000 1000 0000 1204 0000 1203 0000 0000  ................
  0x0050:  5708 0000 0001 0000 1200 0000 4865 6c6c  W...........Hell
  0x0060:  6f20 576f 726c 643a 2032 3133 3500 0000  o.World:.2135...

关于此数据包的一些要注意的功能:

  • 消息内容“Hello World: 2135”以明文形式发送。

  • 源IP地址和目标IP地址为``localhost``:由于两个节点在同一台计算机上运行,节点通过``localhost``接口相互发现。

启用加密功能。

停止讲话者和听话者节点。通过设置安全环境变量为两者启用加密,并重新运行它们。

# In terminal 1:
export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keys
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker

# In terminal 2:
export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keys
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener

显示加密的发现数据包

运行与之前相同的``tcpdump``命令,以查看启用加密后的发现流量的输出:

sudo tcpdump -X -i any udp port 7400

典型的发现数据包的外观类似于以下内容:

21:09:07.336617 IP 8_xterm.60409 > 239.255.0.1.7400: UDP, length 596
  0x0000:  4500 0270 c2f6 4000 0111 83d6 c0a8 8007  E..p..@.........
  0x0010:  efff 0001 ebf9 1ce8 025c 331e 5254 5053  .........\3.RTPS
  0x0020:  0203 010f bbdd 199c 7522 b6cb 699f 74ae  ........u"..i.t.
  ...
  0x00c0:  5800 0400 3f0c ff0f 6200 2000 1a00 0000  X...?...b.......
  0x00d0:  2f74 616c 6b65 725f 6c69 7374 656e 6572  /talker_listener
  0x00e0:  2f6c 6973 7465 6e65 7200 0000 2c00 2800  /listener...,.(.
  0x00f0:  2300 0000 656e 636c 6176 653d 2f74 616c  #...enclave=/tal
  0x0100:  6b65 725f 6c69 7374 656e 6572 2f6c 6973  ker_listener/lis
  0x0110:  7465 6e65 723b 0000 0110 c400 1400 0000  tener;..........
  0x0120:  4444 533a 4175 7468 3a50 4b49 2d44 483a  DDS:Auth:PKI-DH:
  0x0130:  312e 3000 0400 0000 0c00 0000 6464 732e  1.0.........dds.
  ...
  0x0230:  1100 0000 6464 732e 7065 726d 5f63 612e  ....dds.perm_ca.
  0x0240:  616c 676f 0000 0000 0d00 0000 4543 4453  algo........ECDS
  0x0250:  412d 5348 4132 3536 0000 0000 0000 0000  A-SHA256........
  0x0260:  0510 0800 0700 0080 0600 0080 0100 0000  ................

这个数据包要大得多,其中包含可用于在ROS节点之间建立加密的信息。很快我们会看到,实际上这些信息包括了在启用安全性时创建的一些安全配置文件。想了解更多吗?可以查看优秀论文《网络侦察和漏洞挖掘安全DDS系统》<https://arxiv.org/abs/1908.05310>,以了解为什么这很重要。

显示加密的数据包

现在使用``tcpdump``来捕获数据包:

sudo tcpdump -i any -X udp portrange 7401-7500

一个典型的数据包如下所示:

21:18:14.531102 IP localhost.54869 > localhost.7415: UDP, length 328
  0x0000:  4500 0164 bb42 4000 4011 8044 7f00 0001  E..d.B@.@..D....
  0x0010:  7f00 0001 d655 1cf7 0150 ff63 5254 5053  .....U...P.cRTPS
  0x0020:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J
  0x0030:  3301 1400 0000 0003 492a 6066 8603 cdb5  3.......I*`f....
  0x0040:  9df6 5da6 8402 2136 0c01 1400 0000 0000  ..]...!6........
  0x0050:  0203 010f daf7 10ce d977 449b bb33 f04a  .........wD..3.J
  ...
  0x0130:  7905 d390 3201 1400 3ae5 0b60 3906 967e  y...2...:..`9..~
  0x0140:  5b17 fd42 de95 54b9 0000 0000 3401 1400  [..B..T.....4...
  0x0150:  42ae f04d 0559 84c5 7116 1c51 91ba 3799  B..M.Y..q..Q..7.
  0x0160:  0000 0000                                ....

此RTPS数据包中的所有数据均已加密。

除了此数据包外,您还应该看到包含节点和飞地名称的其他数据包;这些支持其他ROS功能,如参数和服务。这些数据包的加密选项也可以通过安全策略进行控制。