Appearance
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 来保持相同的发现体验。
高层步骤:
- 在 Gateway 主机上运行一个 DNS 服务器(可通过 Tailnet 访问)。
- 在专用区域(例如
openclaw.internal.)下为_openclaw-gw._tcp发布 DNS-SD 记录。 - 配置 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 +shortTailscale 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=gatewaydisplayName=<friendly name>lanHost=<hostname>.localgatewayPort=<port>(Gateway WS + HTTP)gatewayTls=1(仅在 TLS 启用时)gatewayTlsSha256=<sha256>(仅在 TLS 启用且指纹可用时)canvasPort=<port>(仅在 canvas host 启用时;目前与gatewayPort相同)transport=gatewaytailnetDns=<magicdns>(mDNS 完整模式下可选提示,当 Tailnet 可用时)sshPort=<port>(完整模式下才有;minimal 和 off 模式省略)cliPath=<path>(完整模式下才有;minimal 和 off 模式省略)
安全说明:
- Bonjour/mDNS TXT 记录未经认证。客户端不得将 TXT 作为权威路由依据。
- 客户端应使用解析的服务端点(SRV + A/AAAA)进行路由。将
lanHost、tailnetDns、gatewayPort和gatewayTlsSha256仅视为提示。 - SSH 自动目标也应使用解析的服务主机,而不是仅基于 TXT 的提示。
- TLS 固定绝不允许广播的
gatewayTlsSha256覆盖之前存储的固定值。 - iOS/Android 节点应将基于发现的直连视为仅 TLS,并在信任首次指纹前需要明确的用户确认。
macOS 上的调试
有用的内置工具:
浏览实例:
bashdns-sd -B _openclaw-gw._tcp local.解析一个实例(替换
<instance>):bashdns-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 resolvedbonjour: watchdog detected non-announced service ...bonjour: disabling advertiser after ... failed restarts ...
看门狗将活跃的 probing、announcing 和新冲突重命名视为进行中状态。如果服务从未达到 announced,OpenClaw 最终会重新创建广告器,并在多次失败后禁用该 Gateway 进程的 Bonjour,而不是永远重新广告。
Bonjour 使用系统主机名作为广告的 .local 主机(当它是有效 DNS 标签时)。如果系统主机名包含空格、下划线或其他无效 DNS 标签字符,OpenClaw 回退到 openclaw.local。如需明确的主机标签,在启动 Gateway 前设置 OPENCLAW_MDNS_HOSTNAME=<name>。
在 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;仅当客户端需要 cliPath 或 sshPort 提示时才使用 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 bonjourDocker 注意事项
内置的 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:
确认 Gateway 处于自动、强制开启或强制关闭模式:
bashdocker compose config | grep OPENCLAW_DISABLE_BONJOUR确认 Gateway 本身可通过发布端口访问:
bashcurl -fsS http://127.0.0.1:18789/healthz当 Bonjour 禁用时,使用直接目标:
- 控制 UI 或本地工具:
http://127.0.0.1:18789 - LAN 客户端:
http://<gateway-host>:18789 - 跨网络客户端:Tailnet MagicDNS、Tailnet IP、SSH 隧道或广域 DNS-SD
- 控制 UI 或本地工具:
如果你在 Docker 中故意启用了 Bonjour 插件并用
OPENCLAW_DISABLE_BONJOUR=0强制广告,从主机测试组播:bashdns-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 值包括1、true、yes和on(旧版:OPENCLAW_DISABLE_BONJOUR)。OPENCLAW_DISABLE_BONJOUR=0强制开启 LAN 组播广告,包括在检测到的容器内;接受的 falsy 值包括0、false、no和off。- 当 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)。
相关文档
- 发现策略和传输选择:发现与传输
- 节点配对 + 审批:Gateway 配对
常见问题
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 failed、name conflict resolved 或 disabling advertiser 等条目。如有需要,设置 OPENCLAW_MDNS_HOSTNAME=<name> 强制指定广告主机名。