coily channel: pure-Go resolver bypasses Tailscale MagicDNS on Linux #101
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
coily channel read <id>fails from kai-server with:curl http://apifrom the same shell on the same host works fine and resolvesapito a tailnet IP (100.126.181.22at the time of writing).Cause
Coily is built with Go's default pure-Go resolver. The pure-Go resolver reads
/etc/resolv.confdirectly and sends queries to whatever nameserver is listed there. On Ubuntu kai-server that is127.0.0.53(systemd-resolved), which does not know Tailscale MagicDNS names. The pure-Go resolver does not consult/etc/nsswitch.conf, so it bypasses the Tailscale resolver entry that libc-based clients (curl,getent hosts,ssh, anything that callsgetaddrinfo) honor.This is a known Go-on-Linux footgun. Reference: golang/go#57757, Tailscale's MagicDNS doc (notes the systemd-resolved + Go interaction).
Fix options, ranked
Build with cgo resolver - add
-tags netcgoto the release build, orimport _ "net"withGODEBUG=netdns=cgo+1baked in. This routes Go's net package through libcgetaddrinfo, picking up nsswitch and the Tailscale entry. Lowest blast radius, no runtime config, fixes every coily verb that opens an HTTP connection, not justchannel. Cost: cgo enabled = need C toolchain at build time. The release builds already use cgo on macOS for keychain access, so this is incremental on Linux only.Runtime env in the systemd unit / shell rc - set
GODEBUG=netdns=cgoin whatever launchescoily. Works, but every host has to be configured, including ad-hoc shells, so it drifts.Resolve via the Tailscale local API - tailscaled exposes a Unix socket at
/var/run/tailscale/tailscaled.sockand Tailscale's Go library hastailscale.com/client/tailscale.LocalClientwith aWhoIs/LookupHostnamesurface. Coily could ask tailscaled directly when the requested host is a bare hostname or*.ts.net. More invasive, only helps the tailnet path, and breaks on hosts where tailscaled isn't local. Mostly mentioned for completeness - not the right call here.Option 1 is the right move. Option 2 unblocks Kai today (
GODEBUG=netdns=cgo coily channel read <id>works, verified).Acceptance
coily channel read <id>against a MagicDNS hostname succeeds from kai-server with no per-shell env tweak.Provenance
Surfaced in agentic-os-kai#292 while teaching Claude about the o2r agent-channel surface.