Files
openclaw/docs/gateway/bonjour.md

164 lines
5.6 KiB
Markdown
Raw Normal View History

---
summary: "Bonjour/mDNS discovery + debugging (Gateway beacons, clients, and common failure modes)"
read_when:
- Debugging Bonjour discovery issues on macOS/iOS
- Changing mDNS service types, TXT records, or discovery UX
---
# Bonjour / mDNS discovery
2026-01-08 23:06:56 +01:00
Clawdbot uses Bonjour (mDNS / DNSSD) as a **LANonly convenience** to discover
an active Gateway bridge. It is besteffort and does **not** replace SSH or
Tailnet-based connectivity.
2026-01-08 23:06:56 +01:00
## Widearea Bonjour (Unicast DNSSD) over Tailscale
2026-01-08 23:06:56 +01:00
If the node and gateway are on different networks, multicast mDNS wont cross the
boundary. You can keep the same discovery UX by switching to **unicast DNSSD**
("WideArea Bonjour") over Tailscale.
2026-01-08 23:06:56 +01:00
Highlevel steps:
2026-01-08 23:06:56 +01:00
1) Run a DNS server on the gateway host (reachable over Tailnet).
2) Publish DNSSD records for `_clawdbot-bridge._tcp` under a dedicated zone
(example: `clawdbot.internal.`).
3) Configure Tailscale **split DNS** so `clawdbot.internal` resolves via that
DNS server for clients (including iOS).
2026-01-08 23:06:56 +01:00
Clawdbot standardizes on `clawdbot.internal.` for this mode. iOS/Android nodes
browse both `local.` and `clawdbot.internal.` automatically.
### Gateway config (recommended)
```json5
{
bridge: { bind: "tailnet" }, // tailnet-only (recommended)
2026-01-04 14:32:47 +00:00
discovery: { wideArea: { enabled: true } } // enables clawdbot.internal DNS-SD publishing
}
```
2026-01-08 23:06:56 +01:00
### Onetime DNS server setup (gateway host)
```bash
2026-01-04 14:32:47 +00:00
clawdbot dns setup --apply
```
This installs CoreDNS and configures it to:
2026-01-08 23:06:56 +01:00
- listen on port 53 only on the gateways Tailscale interfaces
- serve `clawdbot.internal.` from `~/.clawdbot/dns/clawdbot.internal.db`
2026-01-08 23:06:56 +01:00
Validate from a tailnetconnected machine:
```bash
2026-01-04 14:32:47 +00:00
dns-sd -B _clawdbot-bridge._tcp clawdbot.internal.
dig @<TAILNET_IPV4> -p 53 _clawdbot-bridge._tcp.clawdbot.internal PTR +short
```
### Tailscale DNS settings
In the Tailscale admin console:
- Add a nameserver pointing at the gateways tailnet IP (UDP/TCP 53).
2026-01-04 14:32:47 +00:00
- Add split DNS so the domain `clawdbot.internal` uses that nameserver.
2026-01-08 23:06:56 +01:00
Once clients accept tailnet DNS, iOS nodes can browse
`_clawdbot-bridge._tcp` in `clawdbot.internal.` without multicast.
### Bridge listener security (recommended)
2026-01-08 23:06:56 +01:00
The bridge port (default `18790`) is a plain TCP service. By default it binds to
`0.0.0.0`, which makes it reachable from any interface on the gateway host.
2026-01-08 23:06:56 +01:00
For tailnetonly setups:
2026-01-04 14:32:47 +00:00
- Set `bridge.bind: "tailnet"` in `~/.clawdbot/clawdbot.json`.
2026-01-08 23:06:56 +01:00
- Restart the Gateway (or restart the macOS menubar app).
## What advertises
2026-01-08 23:06:56 +01:00
Only the Gateway (when the **bridge is enabled**) advertises `_clawdbot-bridge._tcp`.
## Service types
2026-01-04 14:32:47 +00:00
- `_clawdbot-bridge._tcp` — bridge transport beacon (used by macOS/iOS/Android nodes).
2026-01-08 23:06:56 +01:00
## TXT keys (nonsecret hints)
2026-01-08 23:06:56 +01:00
The Gateway advertises small nonsecret hints to make UI flows convenient:
- `role=gateway`
2026-01-08 23:06:56 +01:00
- `displayName=<friendly name>`
- `lanHost=<hostname>.local`
2026-01-08 23:06:56 +01:00
- `gatewayPort=<port>` (informational; Gateway WS is usually loopbackonly)
- `bridgePort=<port>` (only when bridge is enabled)
2026-01-08 23:06:56 +01:00
- `canvasPort=<port>` (only when the canvas host is enabled; default `18793`)
- `sshPort=<port>` (defaults to 22 when not overridden)
- `transport=bridge`
- `cliPath=<path>` (optional; absolute path to a runnable `clawdbot` entrypoint)
- `tailnetDns=<magicdns>` (optional hint when Tailnet is available)
## Debugging on macOS
2026-01-08 23:06:56 +01:00
Useful builtin tools:
- Browse instances:
2026-01-08 23:06:56 +01:00
```bash
dns-sd -B _clawdbot-bridge._tcp local.
```
- Resolve one instance (replace `<instance>`):
2026-01-08 23:06:56 +01:00
```bash
dns-sd -L "<instance>" _clawdbot-bridge._tcp local.
```
2026-01-08 23:06:56 +01:00
If browsing works but resolving fails, youre usually hitting a LAN policy or
mDNS resolver issue.
## Debugging in Gateway logs
2026-01-08 23:06:56 +01:00
The Gateway writes a rolling log file (printed on startup as
`gateway log file: ...`). Look for `bonjour:` lines, especially:
2026-01-08 23:06:56 +01:00
- `bonjour: advertise failed ...`
- `bonjour: ... name conflict resolved` / `hostname conflict resolved`
2026-01-08 23:06:56 +01:00
- `bonjour: watchdog detected non-announced service ...`
2025-12-18 13:18:33 +01:00
## Debugging on iOS node
2026-01-08 23:06:56 +01:00
The iOS node uses `NWBrowser` to discover `_clawdbot-bridge._tcp`.
2026-01-08 23:06:56 +01:00
To capture logs:
- Settings → Bridge → Advanced → **Discovery Debug Logs**
- Settings → Bridge → Advanced → **Discovery Logs** → reproduce → **Copy**
2026-01-08 23:06:56 +01:00
The log includes browser state transitions and resultset changes.
## Common failure modes
2026-01-08 23:06:56 +01:00
- **Bonjour doesnt cross networks**: use Tailnet or SSH.
- **Multicast blocked**: some WiFi networks disable mDNS.
- **Sleep / interface churn**: macOS may temporarily drop mDNS results; retry.
- **Browse works but resolve fails**: keep machine names simple (avoid emojis or
punctuation), then restart the Gateway. The bridge instance name derives from
the host name, so overly complex names can confuse some resolvers.
## Escaped instance names (`\032`)
2026-01-08 23:06:56 +01:00
Bonjour/DNSSD often escapes bytes in service instance names as decimal `\DDD`
sequences (e.g. spaces become `\032`).
- This is normal at the protocol level.
2026-01-08 23:06:56 +01:00
- UIs should decode for display (iOS uses `BonjourEscapes.decode`).
## Disabling / configuration
2026-01-04 14:32:47 +00:00
- `CLAWDBOT_DISABLE_BONJOUR=1` disables advertising.
2026-01-08 23:06:56 +01:00
- `CLAWDBOT_BRIDGE_ENABLED=0` disables the bridge listener (and the bridge beacon).
- `bridge.bind` / `bridge.port` in `~/.clawdbot/clawdbot.json` control bridge bind/port.
- `CLAWDBOT_BRIDGE_HOST` / `CLAWDBOT_BRIDGE_PORT` still work as backcompat overrides.
- `CLAWDBOT_SSH_PORT` overrides the SSH port advertised in TXT.
- `CLAWDBOT_TAILNET_DNS` publishes a MagicDNS hint in TXT.
- `CLAWDBOT_CLI_PATH` overrides the advertised CLI path.
## Related docs
2026-01-10 14:51:21 -06:00
- Discovery policy and transport selection: [Discovery](/gateway/discovery)
- Node pairing + approvals: [Gateway pairing](/gateway/pairing)