Skip to content

OpenClaw 使用 Bonjour(mDNS/DNS-SD)在局域网内自动发现 Gateway(WebSocket 端点),该机制为 Lan-only 便利手段,不能替代 SSH 或 Tailnet 连接。跨网络场景可通过 Tailscale 切换为单播 DNS-SD 保持相同发现体验;Docker 容器默认自动禁用 Bonjour,可通过 OPENCLAW_DISABLE_BONJOUR=0 强制开启(仅限 host/macvlan 网络)。排查时使用 dns-sd -B _openclaw-gw._tcp local. 浏览实例,或查看 Gateway 日志中以 bonjour: 开头的行。

OpenClaw Bonjour/mDNS 局域网发现配置与故障排查

OpenClaw 使用 Bonjour(mDNS / DNS-SD)发现活动 Gateway(WebSocket 端点)。组播 local. 浏览是仅限局域网的便利功能。内置的 bonjour 插件负责 LAN 广告:在 macOS 主机上自动启动,在 Linux、Windows 和容器化 Gateway 部署中为选择加入。对于跨网络发现,相同的 beacon 也可以通过配置的广域 DNS-SD 域发布。发现仍然是尽力而为的,不能替代 SSH 或 Tailnet 连接。

广域 Bonjour(单播 DNS-SD)over Tailscale

如果节点和 Gateway 位于不同网络,组播 mDNS 无法跨越边界。你可以切换到 单播 DNS-SD("Wide-Area Bonjour")over Tailscale 来保持相同的发现体验。

高层步骤:

  1. 在 Gateway 主机上运行一个 DNS 服务器(可通过 Tailnet 访问)。
  2. 在专用区域(例如 openclaw.internal.)下为 _openclaw-gw._tcp 发布 DNS-SD 记录。
  3. 配置 Tailscale split DNS,使你选择的域名通过该 DNS 服务器为客户端(包括 iOS)解析。

OpenClaw 支持任意发现域;openclaw.internal. 只是示例。iOS/Android 节点同时浏览 local. 和你配置的广域域名。

Gateway 配置(推荐)

json5
{
  gateway: { bind: "tailnet" }, // 仅 tailnet(推荐)
  discovery: { wideArea: { enabled: true } }, // 启用广域 DNS-SD 发布
}

一次性 DNS 服务器设置(Gateway 主机)

bash
openclaw dns setup --apply

这会安装 CoreDNS 并配置为:

  • 仅在 Gateway 的 Tailscale 接口上监听 53 端口
  • ~/.openclaw/dns/<domain>.db 提供你选择的域(例如 openclaw.internal.

从连接到 tailnet 的机器上验证:

bash
dns-sd -B _openclaw-gw._tcp openclaw.internal.
dig @<TAILNET_IPV4> -p 53 _openclaw-gw._tcp.openclaw.internal PTR +short

Tailscale DNS 设置

在 Tailscale 管理控制台中:

  • 添加一个指向 Gateway tailnet IP 的名称服务器(UDP/TCP 53)。
  • 添加 split DNS,使你的发现域使用该名称服务器。

客户端接受 tailnet DNS 后,iOS 节点就可以在你的发现域中浏览 _openclaw-gw._tcp,无需组播。

Gateway 监听器安全(推荐)

Gateway WS 端口(默认 18789)默认绑定到 loopback。对于 LAN/tailnet 访问,请显式绑定并保持认证启用。

对于仅限 tailnet 的设置:

  • ~/.openclaw/openclaw.json 中设置 gateway.bind: "tailnet"
  • 重启 Gateway(或重启 macOS 菜单栏应用)。

广播方

只有 Gateway 广播 _openclaw-gw._tcp。LAN 组播广告由内置的 bonjour 插件在插件启用时提供;广域 DNS-SD 发布始终由 Gateway 负责。

服务类型

  • _openclaw-gw._tcp — Gateway 传输信标(macOS/iOS/Android 节点使用)

TXT 键值(非机密提示)

Gateway 广播少量非机密提示以方便 UI 流程:

  • role=gateway
  • displayName=<friendly name>
  • lanHost=&lt;hostname&gt;.local
  • gatewayPort=&lt;port&gt;(Gateway WS + HTTP)
  • gatewayTls=1(仅在 TLS 启用时)
  • gatewayTlsSha256=&lt;sha256&gt;(仅在 TLS 启用且指纹可用时)
  • canvasPort=&lt;port&gt;(仅在 canvas host 启用时;目前与 gatewayPort 相同)
  • transport=gateway
  • tailnetDns=&lt;magicdns&gt;(mDNS 完整模式下可选提示,当 Tailnet 可用时)
  • sshPort=&lt;port&gt;(完整模式下才有;minimal 和 off 模式省略)
  • cliPath=&lt;path&gt;(完整模式下才有;minimal 和 off 模式省略)

安全说明:

  • Bonjour/mDNS TXT 记录未经认证。客户端不得将 TXT 作为权威路由依据。
  • 客户端应使用解析的服务端点(SRV + A/AAAA)进行路由。将 lanHosttailnetDnsgatewayPortgatewayTlsSha256 仅视为提示。
  • SSH 自动目标也应使用解析的服务主机,而不是仅基于 TXT 的提示。
  • TLS 固定绝不允许广播的 gatewayTlsSha256 覆盖之前存储的固定值。
  • iOS/Android 节点应将基于发现的直连视为仅 TLS,并在信任首次指纹前需要明确的用户确认。

macOS 上的调试

有用的内置工具:

  • 浏览实例:

    bash
    dns-sd -B _openclaw-gw._tcp local.
  • 解析一个实例(替换 &lt;instance&gt;):

    bash
    dns-sd -L "<instance>" _openclaw-gw._tcp local.

如果浏览成功但解析失败,通常是 LAN 策略或 mDNS 解析器问题。

在 Gateway 日志中调试

Gateway 会写入滚动日志文件(启动时打印为 gateway log file: ...)。查找 bonjour: 开头的行,尤其是:

  • bonjour: advertise failed ...
  • bonjour: suppressing ciao cancellation ...
  • bonjour: ... name conflict resolved / hostname conflict resolved
  • bonjour: watchdog detected non-announced service ...
  • bonjour: disabling advertiser after ... failed restarts ...

看门狗将活跃的 probingannouncing 和新冲突重命名视为进行中状态。如果服务从未达到 announced,OpenClaw 最终会重新创建广告器,并在多次失败后禁用该 Gateway 进程的 Bonjour,而不是永远重新广告。

Bonjour 使用系统主机名作为广告的 .local 主机(当它是有效 DNS 标签时)。如果系统主机名包含空格、下划线或其他无效 DNS 标签字符,OpenClaw 回退到 openclaw.local。如需明确的主机标签,在启动 Gateway 前设置 OPENCLAW_MDNS_HOSTNAME=&lt;name&gt;

在 iOS 节点上调试

iOS 节点使用 NWBrowser 发现 _openclaw-gw._tcp

抓取日志:

  • 设置 → Gateway → 高级 → Discovery Debug Logs
  • 设置 → Gateway → 高级 → Discovery Logs → 复现 → Copy

日志包含浏览器状态转换和结果集变更。

何时启用 Bonjour

Bonjour 在 macOS 主机的空配置 Gateway 启动时自动启动,因为本地 app 和附近的 iOS/Android 节点通常依赖同 LAN 发现。

在 Linux、Windows 或其他非 macOS 主机上,当同 LAN 自动发现有用时,显式启用 Bonjour:

bash
openclaw plugins enable bonjour

启用后,Bonjour 使用 discovery.mdns.mode 决定发布多少 TXT 元数据。相同的模式控制广域 DNS-SD 记录中的可选 TXT 提示。默认模式是 minimal;仅当客户端需要 cliPathsshPort 提示时才使用 full。使用 off 模式可在不更改插件启用状态的情况下抑制 LAN 组播;当 discovery.wideArea.enabled 为 true 时,广域 DNS-SD 仍可发布最小的 Gateway beacon。

何时禁用 Bonjour

当 LAN 组播广告不必要、不可用或有害时,保持 Bonjour 禁用。常见场景:非 macOS 服务器、Docker bridge 网络、WSL,或网络策略丢弃 mDNS 组播。在这些环境中,Gateway 仍可通过其发布 URL、SSH、Tailnet 或广域 DNS-SD 访问,但 LAN 自动发现不可靠。

当问题限于部署范围时,优先使用现有环境变量覆盖:

bash
OPENCLAW_DISABLE_BONJOUR=1

这会禁用 LAN 组播广告,而不更改插件配置。它适用于 Docker 镜像、服务文件、启动脚本和一次性调试,因为设置随环境消失。

当你故意想要关闭该 OpenClaw 配置的内置 LAN 发现插件时,使用插件配置:

bash
openclaw plugins disable bonjour

Docker 注意事项

内置的 Bonjour 插件在检测到的容器中自动禁用 LAN 组播广告(当 OPENCLAW_DISABLE_BONJOUR 未设置时)。Docker bridge 网络通常不转发 mDNS 组播(224.0.0.251:5353)到容器和 LAN 之间,因此从容器广告很少使发现工作。

重要注意点:

  • Bonjour 在 macOS 主机上自动启动,在其他平台为选择加入。保持禁用不会停止 Gateway;它只跳过 LAN 组播广告。
  • 禁用 Bonjour 不会改变 gateway.bind;Docker 仍默认为 OPENCLAW_GATEWAY_BIND=lan,因此发布的主机端口可用。
  • 禁用 Bonjour 不会禁用广域 DNS-SD。当 Gateway 和节点不在同一 LAN 时,使用广域发现或 Tailnet。
  • 在 Docker 外部重用相同的 OPENCLAW_CONFIG_DIR 不会持久化容器自动禁用策略。
  • 仅在 host 网络、macvlan 或其他已知通过 mDNS 组播的网络中设置 OPENCLAW_DISABLE_BONJOUR=0;设置为 1 强制禁用。

禁用 Bonjour 后的故障排查

如果节点在 Docker 设置后无法自动发现 Gateway:

  1. 确认 Gateway 处于自动、强制开启或强制关闭模式:

    bash
    docker compose config | grep OPENCLAW_DISABLE_BONJOUR
  2. 确认 Gateway 本身可通过发布端口访问:

    bash
    curl -fsS http://127.0.0.1:18789/healthz
  3. 当 Bonjour 禁用时,使用直接目标:

    • 控制 UI 或本地工具:http://127.0.0.1:18789
    • LAN 客户端:http://&lt;gateway-host&gt;:18789
    • 跨网络客户端:Tailnet MagicDNS、Tailnet IP、SSH 隧道或广域 DNS-SD
  4. 如果你在 Docker 中故意启用了 Bonjour 插件并用 OPENCLAW_DISABLE_BONJOUR=0 强制广告,从主机测试组播:

    bash
    dns-sd -B _openclaw-gw._tcp local.

    如果浏览为空或 Gateway 日志显示重复的 ciao 看门狗取消,恢复 OPENCLAW_DISABLE_BONJOUR=1 并使用直接或 Tailnet 路由。

常见失败模式

  • Bonjour 无法跨网络:使用 Tailnet 或 SSH。
  • 组播被阻止:某些 Wi-Fi 网络禁用 mDNS。
  • 广告器卡在 probing/announcing:组播被阻止的主机、容器 bridge、WSL 或接口抖动可能导致 ciao 广告器停留在非 announced 状态。OpenClaw 重试几次后禁用该 Gateway 进程的 Bonjour,而不是永远重启广告器。
  • Docker bridge 网络:Bonjour 在检测到的容器中自动禁用。仅在 host、macvlan 或其他支持 mDNS 的网络中设置 OPENCLAW_DISABLE_BONJOUR=0
  • 休眠/接口抖动:macOS 可能临时丢失 mDNS 结果,重试。
  • 浏览成功但解析失败:保持机器名称简单(避免 emoji 或标点),然后重启 Gateway。服务实例名称来源于主机名,过于复杂的名称可能使某些解析器混淆。

转义的实例名称(\032

Bonjour/DNS-SD 通常将服务实例名称中的字节转义为十进制 \DDD 序列(例如空格变为 \032)。

  • 这在协议层面是正常的。
  • UI 应在显示时解码(iOS 使用 BonjourEscapes.decode)。

启用/禁用/配置

  • macOS 主机默认自动启动内置的 LAN 发现插件。
  • openclaw plugins enable bonjour 在未默认启用的主机上启用内置 LAN 发现插件。
  • openclaw plugins disable bonjour 通过禁用内置插件来禁用 LAN 组播广告。
  • OPENCLAW_DISABLE_BONJOUR=1 禁用 LAN 组播广告而不改变插件配置;接受的 truthy 值包括 1trueyeson(旧版:OPENCLAW_DISABLE_BONJOUR)。
  • OPENCLAW_DISABLE_BONJOUR=0 强制开启 LAN 组播广告,包括在检测到的容器内;接受的 falsy 值包括 0falsenooff
  • 当 Bonjour 插件启用且 OPENCLAW_DISABLE_BONJOUR 未设置时,Bonjour 在普通主机上广告,在检测到的容器内自动禁用。
  • ~/.openclaw/openclaw.json 中的 gateway.bind 控制 Gateway 绑定模式。
  • OPENCLAW_SSH_PORT 覆盖 TXT 中广告的 SSH 端口(旧版:OPENCLAW_SSH_PORT)。
  • OPENCLAW_TAILNET_DNS 在 TXT 中发布 MagicDNS 提示(mDNS 完整模式启用时)(旧版:OPENCLAW_TAILNET_DNS)。
  • OPENCLAW_CLI_PATH 覆盖广告的 CLI 路径(旧版:OPENCLAW_CLI_PATH)。

相关文档

常见问题

Bonjour 跨网络不工作怎么办?

Bonjour/mDNS 使用组播,无法跨越子网或不同网络。使用 Tailscale 广域 Bonjour(单播 DNS-SD)或直接通过 Tailnet IP / SSH 隧道连接 Gateway。配置方法见上方“广域 Bonjour over Tailscale”部分。

Docker 中 Bonjour 自动禁用,怎么强制开启?

默认情况下 Docker 容器中 Bonjour 自动禁用。在 docker-compose.yml 或运行命令中设置 OPENCLAW_DISABLE_BONJOUR=0,并确保使用 host 网络或 macvlan(bridge 网络不转发 mDNS 组播)。验证组播是否有效:在宿主机运行 dns-sd -B _openclaw-gw._tcp local.,如果为空则恢复为禁用并使用直接连接。

Bonjour 解析失败怎么排查?

首先用 dns-sd -B _openclaw-gw._tcp local. 确认是否能浏览到实例。如果浏览成功但 dns-sd -L 解析失败,检查 LAN 策略或 mDNS 解析器,保持主机名简单(不含空格、emoji)。查看 Gateway 日志中 bonjour: 开头的行,特别是 advertise failedname conflict resolveddisabling advertiser 等条目。如有需要,设置 OPENCLAW_MDNS_HOSTNAME=&lt;name&gt; 强制指定广告主机名。