fix(svc-net-tor): stop pinning the host to a single resolver

54aeba7e0 pinned /etc/resolv.conf at 127.0.0.1 so onion names route
through the role's dnsmasq. That pin has no fallback, so every way
dnsmasq can stop answering takes the whole host's name resolution with
it.

It did. In run 32284541284 job 96178507650 the rescue bundle shows
sockets-udp.txt with zero :53 entries, `dig @127.0.0.1` returning
"connection refused", the dnsmasq process alive (state S, PPID 1) and
systemctl reporting `loaded active running` - 1201 resolution failures
from 21:58:17 onward, never recovering, while CoreDNS on the configured
upstream answered correctly the whole time.

The second entry is the same address dnsmasq already forwards to
(networks.internet.dns, the upstream 54aeba7e0 introduced), so this adds
no new destination: with dnsmasq up, glibc never reaches it; with dnsmasq
down, the host reaches the upstream directly instead of nothing. It is
the instinct plugins/lookup/container_dns.py already documents for
containers - "the clearnet resolver stays as a second entry so that
losing dnsmasq costs onion names rather than all name resolution" - and
daemon.json has carried both entries all along. Only the host was left
without one.

Unconditional, not guarded: router.yml:2-7 asserts networks.internet.dns
is non-empty before the file does anything else, so a guard would be dead
code.

Deliberately not fixing this by dropping bind-dynamic from
templates/dnsmasq-tor-onion.conf.j2. Without the directive dnsmasq binds
0.0.0.0:53, which on Ubuntu collides with systemd-resolved on
127.0.0.53:53 - reproduced on dnsmasq 2.93: "failed to create listening
socket for port ...: Address already in use", exit 2. bind-interfaces is
worse: TOR_CONTAINER_DNS_HOST is a deploy-time docker0 fact, and dnsmasq
starts at boot before docker0 exists. A fallback resolver covers the
listener loss, the bind collision and the boot-order miss at once.

Known trade: while dnsmasq is down, .onion lookups fall through to the
clearnet resolver and return NXDOMAIN instead of timing out. RFC 7686
says .onion must not reach DNS, and the role's own test cannot see this
because it resolves onions through --socks5-hostname.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-08-20 14:23:30 +02:00
1 parent 069df39027
commit bb0e098a9f
1 file changed
+1
+1
View File
@@ -56,6 +56,7 @@
dest: /etc/resolv.conf
content: |
nameserver 127.0.0.1
nameserver {{ networks.internet.dns }}
options ndots:1
owner: root
group: root