2025-12-13 04:28:12 +00:00
|
|
|
|
---
|
|
|
|
|
|
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 / DNS‑SD) as a **LAN‑only convenience** to discover
|
|
|
|
|
|
an active Gateway bridge. It is best‑effort and does **not** replace SSH or
|
|
|
|
|
|
Tailnet-based connectivity.
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
## Wide‑area Bonjour (Unicast DNS‑SD) over Tailscale
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
If the node and gateway are on different networks, multicast mDNS won’t cross the
|
|
|
|
|
|
boundary. You can keep the same discovery UX by switching to **unicast DNS‑SD**
|
|
|
|
|
|
("Wide‑Area Bonjour") over Tailscale.
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
High‑level steps:
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
1) Run a DNS server on the gateway host (reachable over Tailnet).
|
|
|
|
|
|
2) Publish DNS‑SD 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).
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
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.
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2025-12-17 17:01:10 +01:00
|
|
|
|
### Gateway config (recommended)
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2025-12-17 17:01:10 +01:00
|
|
|
|
```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
|
2025-12-17 17:01:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
### One‑time DNS server setup (gateway host)
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2025-12-17 17:01:10 +01:00
|
|
|
|
```bash
|
2026-01-04 14:32:47 +00:00
|
|
|
|
clawdbot dns setup --apply
|
2025-12-17 17:01:10 +01:00
|
|
|
|
```
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2025-12-17 17:01:10 +01:00
|
|
|
|
This installs CoreDNS and configures it to:
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- listen on port 53 only on the gateway’s Tailscale interfaces
|
|
|
|
|
|
- serve `clawdbot.internal.` from `~/.clawdbot/dns/clawdbot.internal.db`
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
Validate from a tailnet‑connected machine:
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
|
|
|
|
|
```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
|
2025-12-17 14:14:17 +01:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Tailscale DNS settings
|
|
|
|
|
|
|
|
|
|
|
|
In the Tailscale admin console:
|
|
|
|
|
|
|
|
|
|
|
|
- Add a nameserver pointing at the gateway’s tailnet IP (UDP/TCP 53).
|
2026-01-04 14:32:47 +00:00
|
|
|
|
- Add split DNS so the domain `clawdbot.internal` uses that nameserver.
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
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.
|
2025-12-17 14:14:17 +01:00
|
|
|
|
|
2025-12-17 14:27:49 +01:00
|
|
|
|
### 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.
|
2025-12-17 14:27:49 +01:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
For tailnet‑only 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).
|
2025-12-17 14:27:49 +01:00
|
|
|
|
|
2025-12-13 04:28:12 +00:00
|
|
|
|
## What advertises
|
|
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
Only the Gateway (when the **bridge is enabled**) advertises `_clawdbot-bridge._tcp`.
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
|
|
|
|
|
## Service types
|
|
|
|
|
|
|
2026-01-04 14:32:47 +00:00
|
|
|
|
- `_clawdbot-bridge._tcp` — bridge transport beacon (used by macOS/iOS/Android nodes).
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
## TXT keys (non‑secret hints)
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
The Gateway advertises small non‑secret hints to make UI flows convenient:
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2025-12-19 23:12:52 +01:00
|
|
|
|
- `role=gateway`
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- `displayName=<friendly name>`
|
2025-12-13 04:28:12 +00:00
|
|
|
|
- `lanHost=<hostname>.local`
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- `gatewayPort=<port>` (informational; Gateway WS is usually loopback‑only)
|
2025-12-13 04:28:12 +00:00
|
|
|
|
- `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)
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
|
|
|
|
|
## Debugging on macOS
|
|
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
Useful built‑in tools:
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
|
|
|
|
|
- Browse instances:
|
2026-01-08 23:06:56 +01:00
|
|
|
|
```bash
|
|
|
|
|
|
dns-sd -B _clawdbot-bridge._tcp local.
|
|
|
|
|
|
```
|
2025-12-13 04:28:12 +00:00
|
|
|
|
- Resolve one instance (replace `<instance>`):
|
2026-01-08 23:06:56 +01:00
|
|
|
|
```bash
|
|
|
|
|
|
dns-sd -L "<instance>" _clawdbot-bridge._tcp local.
|
|
|
|
|
|
```
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
If browsing works but resolving fails, you’re usually hitting a LAN policy or
|
|
|
|
|
|
mDNS resolver issue.
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
2025-12-14 04:34:26 +00:00
|
|
|
|
## 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:
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- `bonjour: advertise failed ...`
|
2025-12-14 04:34:26 +00:00
|
|
|
|
- `bonjour: ... name conflict resolved` / `hostname conflict resolved`
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- `bonjour: watchdog detected non-announced service ...`
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2025-12-18 13:18:33 +01:00
|
|
|
|
## Debugging on iOS node
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
The iOS node uses `NWBrowser` to discover `_clawdbot-bridge._tcp`.
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
To capture logs:
|
|
|
|
|
|
- Settings → Bridge → Advanced → **Discovery Debug Logs**
|
|
|
|
|
|
- Settings → Bridge → Advanced → **Discovery Logs** → reproduce → **Copy**
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
The log includes browser state transitions and result‑set changes.
|
2025-12-14 04:34:26 +00:00
|
|
|
|
|
2025-12-13 04:28:12 +00:00
|
|
|
|
## Common failure modes
|
|
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- **Bonjour doesn’t cross networks**: use Tailnet or SSH.
|
|
|
|
|
|
- **Multicast blocked**: some Wi‑Fi 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`)
|
2025-12-13 12:28:16 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
Bonjour/DNS‑SD often escapes bytes in service instance names as decimal `\DDD`
|
|
|
|
|
|
sequences (e.g. spaces become `\032`).
|
2025-12-13 12:28:16 +00:00
|
|
|
|
|
|
|
|
|
|
- This is normal at the protocol level.
|
2026-01-08 23:06:56 +01:00
|
|
|
|
- UIs should decode for display (iOS uses `BonjourEscapes.decode`).
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
|
|
|
|
|
## 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 back‑compat 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.
|
2025-12-13 04:28:12 +00:00
|
|
|
|
|
|
|
|
|
|
## 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)
|