【ROS】ROS2 + Zenoh ACL 与配置指南

ROS2 + Zenoh ACL 与配置指南

rmw_zenoh_cpp 的环境变量、配置加载、ACL 设置参考手册


1. 通信架构概览

ROS2 使用 rmw_zenoh_cpp 时有两种通信模式

模式 A:Peer 模式(默认,无独立 Router)

Node1 ──── Node2
Node1 ──── Node3
  • 每个节点内部自带嵌入式 zenohd
  • 节点之间以 P2P 网状连接
  • 通过 scouting(组播)互相发现
  • ACL 不生效——没有集中 Router,无法拦截

模式 B:独立 Router 模式(推荐生产用)

Node1 ─┐
Node2 ─┼── zenohd(独立进程)── Node4
Node3 ─┘
  • 所有节点以 Client 模式连接到中心 Router
  • 消息全部经过 Router 转发
  • ACL 只在这种模式下生效

2. 环境变量大全

2.1 完整变量表

变量用途默认值适用于
ZENOH_ROUTER_CONFIG_URIRouter 配置文件路径DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5Router
ZENOH_SESSION_CONFIG_URISession 配置文件路径DEFAULT_RMW_ZENOH_SESSION_CONFIG.json5Session
ZENOH_CONFIG_OVERRIDEInline 覆盖 key=value两者皆可
ZENOH_ROUTER_CHECK_ATTEMPTSRouter 连接重试次数1Session
RMW_IMPLEMENTATION指定 RMW 实现系统默认Session
ROS_DOMAIN_IDROS2 域 ID默认Session

2.2 ZENOH_CONFIG_OVERRIDE 详解

这是 rmw_zenoh_cpp(Humble 0.1.x)中唯一的 inline 配置方式。语法:

key1="value1";key2/subkey=["val1","val2"];key3=true
  • ; 分隔多个字段
  • JSON5 值用 = 赋值
  • 支持多层嵌套路径(用 /

示例:

# Client 模式 + 指定连接端点
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/192.168.1.100:7447"]'

# Router 模式 + 修改监听端口
export ZENOH_CONFIG_OVERRIDE='listen/endpoints=["tcp/0.0.0.0:7448"]'

# 禁用组播
export ZENOH_CONFIG_OVERRIDE='scouting/multicast/enabled=false'

# 组合多个
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/10.0.0.1:7447"];scouting/multicast/enabled=false'

2.3 关于 RMW_ZENOH_SESSION_CONFIG

这个变量在 rmw_zenoh_cpp 官方源码中从未定义过,是一个不存在的变量。合法的方式只有 ZENOH_CONFIG_OVERRIDE

变量官方支持说明
RMW_ZENOH_SESSION_CONFIG❌ 不存在非官方变量,无任何作用
ZENOH_CONFIG_OVERRIDE✅ 支持唯一 inline 方式

3. 使用方式

3.1 Router 配置

# 方式 1:配置文件
export ZENOH_ROUTER_CONFIG_URI=/path/to/router_config.json5
ros2 run rmw_zenoh_cpp rmw_zenohd

# 方式 2:Inline 覆盖
export ZENOH_CONFIG_OVERRIDE='listen/endpoints=["tcp/0.0.0.0:7448"]'
ros2 run rmw_zenoh_cpp rmw_zenohd

3.2 Session(ROS2 节点)配置

# 方式 1:配置文件
export ZENOH_SESSION_CONFIG_URI=/path/to/session_config.json5
ros2 run my_package my_node

# 方式 2:Inline 覆盖(常用)
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
export ROS_DOMAIN_ID=24
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/192.168.1.100:7447"]'
ros2 run my_package my_node

3.3 配置文件加载顺序(rmw_zenoh_cpp 源码逻辑)

  1. ZENOH_ROUTER_CONFIG_URI(Router)或 ZENOH_SESSION_CONFIG_URI(Session)
  2. 如果设置了 → 通过 zenoh::Config::from_file() 加载文件
  3. 如果未设置 → 使用默认文件
    {package_share_dir}/config/DEFAULT_RMW_ZENOH_ROUTER_CONFIG.json5
  4. 然后应用 ZENOH_CONFIG_OVERRIDE 的 key=value 覆盖

覆盖优先级ZENOH_CONFIG_OVERRIDE > 配置文件 > 默认配置

3.4 daemon 注意事项

# 改变 RMW 或 Zenoh 配置后,必须重启 daemon
ros2 daemon stop 2>/dev/null

# 或绕过 daemon
ros2 topic list --no-daemon
ros2 topic echo /topic --no-daemon

4. 重要限制

rmw_zenoh_cpp(Humble 0.1.x)使用的 rmw_zenohd 是上游 zenoh 的 fork,版本较老:

特性rmw_zenohd (Humble)zenohd (upstream 1.0.0+)
配置格式JSON5JSON5
access_control⚠️ 可能不支持✅ 原生支持
autoconnect_strategy✅ 有额外字段❌ 无此字段
配置文件互用⚠️ 不完全兼容完全兼容

如果要用 ACL,推荐使用上游独立 zenohd


5. ACL 配置

5.1 架构前提

ROS2 Node1 ──┐
             ├──→ 独立 zenohd(加载 ACL 配置)──→ ROS2 Node3
ROS2 Node2 ──┘
     ↑                 ↑                     ↑
  rmw_zenoh_cpp     zenohd 1.0.0+        rmw_zenoh_cpp
  连接模式: client   负责路由 + 过滤       连接模式: client

只有中心 Router 模式下 ACL 才生效。

5.2 使用上游独立 zenohd

# 安装上游 zenohd(如果还未安装)
# https://github.com/eclipse-zenoh/zenoh/releases/tag/1.0.0

# 停止 rmw_zenoh_cpp 自带的 rmw_zenohd
kill $(pgrep rmw_zenohd)

# 启动上游 zenohd(加载 ACL 配置)
zenohd -c /path/to/acl_config.json5 &

# ROS2 节点以 client 模式连接
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
export ROS_DOMAIN_ID=24
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/127.0.0.1:7447"]'
ros2 run my_package my_node

5.3 ACL 配置模板

// /etc/zenoh/acl_router_config.json5
{
  mode: "router",
  listen: {
    endpoints: ["tcp/0.0.0.0:7447"]
  },

  access_control: {
    enabled: true,
    default_permission: "deny",

    subjects: [
      { id: "all" },
      { id: "debug_users", usernames: ["debug"] }
    ],

    rules: [
      {
        id: "allow-navigation",
        messages: ["put", "declare_subscriber", "declare_queryable",
                    "query", "reply", "delete"],
        permission: "allow",
        flows: ["egress", "ingress"],
        key_exprs: ["**/navigo/**", "**/arc/**", "**/odom/**", "**/tf/**"]
      },
      {
        id: "allow-diagnostics",
        messages: ["put", "declare_subscriber"],
        permission: "allow",
        key_exprs: ["**/diagnostics**", "**/rosout"]
      },
      {
        id: "allow-debug",
        messages: ["put", "declare_subscriber"],
        permission: "allow",
        key_exprs: ["**/debug/**"]
      }
    ],

    policies: [
      { subjects: ["all"],        rules: ["allow-navigation", "allow-diagnostics"] },
      { subjects: ["debug_users"], rules: ["allow-navigation", "allow-diagnostics", "allow-debug"] }
    ]
  }
}

5.4 ACL 配置结构关系

subjects → 谁(身份)
rules    → 能做什么(对什么 key、什么操作)
policies → 把谁和什么规则绑定
subjects: [{ id: "all" }, { id: "debug_users" }]
rules:    [{ id: "allow-nav", ... }, { id: "deny-sensor", ... }]
policies: [{ subjects: ["all"],        rules: ["allow-nav"] },
           { subjects: ["debug_users"], rules: ["allow-nav", "allow-debug"] }]

5.5 subject 过滤条件

条件说明
interfaces网络接口名(如 wlan0, eth0
usernames用户名(需配合 usrpwd 认证)
cert_common_namesTLS 证书 CN(需配合 TLS)
link_protocols传输协议(如 tcp, tls, quic

空字段 = wildcard(匹配所有)。

5.6 消息类型

类型对应操作
put发布数据
delete删除数据
declare_subscriber声明订阅
query查询请求
reply查询回复
declare_queryable声明可查询对象
liveliness_tokenLiveliness token
liveliness_queryLiveliness 查询
declare_liveliness_subscriberLiveliness 订阅

5.7 安全方案矩阵

安全等级配置场景
全开放默认配置开发、内网测试
Topic 白名单ACL allow 指定 topic 前缀生产(控制可访问的数据)
认证 + ACLusrpwd 认证 + ACL 按用户分组多机器人、调试权限分离
认证 + ACL + TLS全栈加密公网/跨网络场景

6. FAQ

Q1: 如何判断当前是 Peer 模式还是 Router 模式?

ps aux | grep zenohd
# 有进程 → Router 模式
# 无进程 → Peer 模式(组播发现)

Q2: rmw_zenohd 配置文件是 JSON 还是 JSON5?

JSON5。文件名 *.json5,支持:

  • ///* */ 注释
  • 不带引号的 key
  • 尾随逗号

Q3: 如何持久化 Zenoh 配置?

# 写入 .bashrc
cat >> ~/.bashrc << 'EOF'
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
export ROS_DOMAIN_ID=24
export ZENOH_CONFIG_OVERRIDE='mode="client";connect/endpoints=["tcp/192.168.1.100:7447"]'
EOF

或使用配置文件:

export ZENOH_ROUTER_CONFIG_URI=/etc/zenoh/router_config.json5  # 写入 /etc/environment 或 systemd

Q4: ACL 中 default_permission 设置成 deny 后会不会连 rosout 都看不到?

会。需要显式 allow /rosout 和必要的 discovery topic。建议先用 allow 模式调试,逐步收紧为 deny

Q5: 如果只改一个端口,需要写整个配置文件吗?

不需要,用 ZENOH_CONFIG_OVERRIDE

export ZENOH_CONFIG_OVERRIDE='listen/endpoints=["tcp/0.0.0.0:7448"]'

7. 参考链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monster_H777

我直说吧:你的奖励我的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值