fix(dns): move MagicDNS off the range other overlays drop - #15
Conversation
…hip, FQ-CoDel, and shared policy runtime
…nd peer revocation
…er ownership Linux TUN writer staged [32B frame headroom][12B virtio][IP] but passed offset 12, so the kernel received zeros instead of IPv4 and dropped every inbound packet silently. Writer now owns dedicated [12B][IP] buffers. Also: unify BatchSlot AsRef/AsMut on the receive area, drop dead detach/recycle APIs, fix v3 net prefix in reject fallback, single reader ownership (adopt/hook), ingress generation guard, dataplane health states (up/degraded/restarting/down) with restart counters, git-hash + ALPN in status with CLI/daemon mismatch warning, privileged TUN round-trip test.
…ch honesty, A/B knobs Scheduler reports every drop: EnqueueOutcome (Accepted/AcceptedEvicted/ Rejected) with victim lengths for exact gauge reconcile; drain_drops() surfaces CoDel/emergency deltas exactly once; pump + agent sites report all of flow/peer/codel/emergency/transport-full to telemetry. Diagnostic A/B knobs (env): TUNNET_FLOW_PACKET_CAP, TUNNET_TUN_OFFLOAD, TUNNET_QUIC_DATAGRAM_BUFFER_KB, TUNNET_PUMP_BACKOFF_MAX_US. Eager preconnect of routed peers on keep-alive bring-up (kills first- ping-timeout). bench.ps1/sh: exit codes + stderr captured everywhere, no invented 50 Mbps fallback (TCP failure stops), UDP sender/receiver split with sum_received delivered, size x direction matrix, valid flags. Audit section 18.
Tailscale claims 100.64.0.0/10 and installs a SOURCE-matched anti-spoof
rule:
-A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP
Because it matches on source rather than destination, it also drops the
host's own traffic to any of our addresses in that range, including over
loopback. MagicDNS at 100.100.100.53 was inside it, so on any machine
running both products the resolver stayed listening and never received a
query. DNS failed with no error and no log line on either side.
Measured on an affected host: 50 of 50 packets to 100.100.100.53 and 50 of
50 to the node's mesh address were dropped, while a 127.0.0.1 control was
untouched. Tailscale's own resolver answered normally on the same box,
because Tailscale exempts its own address on lo and Tunnet had no such
exemption.
Move the default to 169.254.0.53. RFC 3927 reserves 169.254.0.0/24 and
excludes it from link-local autoconfiguration, so nothing on the link can
take it; link-local is never routed or policed by an overlay filter, and
it avoids the LAN RFC1918 and Managed 10.x ranges that CGNAT was
originally chosen to dodge.
Changing the default alone would only help new installs, because magic_ip
is serialized into the config file. Relocate a stored contested address on
load as well, with a warning naming the override. This is safe to do
locally: nothing derives the resolver address and no peer needs to agree
on it, unlike the mesh addresses.
Note this does NOT fix synthetic peer IPs, which synthetic_ip_for hardcodes
to 100.100.0.0/16 and which both ends derive independently, so they cannot
be relocated without coordination.
UNVERIFIED: the OS DNS integration has not been exercised with a
link-local resolver address on a live host. systemd-resolved and the other
osdns backends accept it in principle, but that needs confirming before
merge.
|
Verified on a live host, with Tailscale up throughout. This resolves the UNVERIFIED caveat in the commit message, though it narrows rather than removes it. What was confirmed Relocation of a stored contested address fired as intended: The address is assigned and the resolver binds to it: And it answers, which is the point of the change: Before this change the same query to What is still not verified The systemd-resolved integration path was not exercised. Two small things noticed while testing
Refs #18 |
|
Superseded by #24. Closing rather than rebasing. This PR relocated the resolver from 100.100.100.53 to 169.254.0.53 to get it out of the range Tailscale's source-matched anti-spoof rule drops. #24 removes the address from that range entirely instead: That is a better fix than mine. Loopback cannot be claimed by another overlay at all, whereas 169.254.0.53 was merely unlikely to be. It also makes the config-relocation-on-load logic unnecessary. It additionally resolves the one thing this PR explicitly could not: Worth keeping from the investigation: on an affected host, 50 of 50 packets to 100.100.100.53 and 50 of 50 to the node's mesh address were dropped, with a 127.0.0.1 control untouched. The failure is silent on both sides, since the resolver stays listening and simply never receives a query. That silence is the reason this took a packet capture to find, and is worth a regression test on whatever address PeerDNS ends up using. The branch is untouched if #24 stalls and this needs reviving. |
Tailscale claims 100.64.0.0/10 and installs a SOURCE-matched anti-spoof rule:
Because it matches on source rather than destination, it also drops the host's own traffic to any of our addresses in that range, including over loopback. MagicDNS at 100.100.100.53 was inside it, so on any machine running both products the resolver stayed listening and never received a query. DNS failed with no error and no log line on either side.
Measured on an affected host: 50 of 50 packets to 100.100.100.53 and 50 of 50 to the node's mesh address were dropped, while a 127.0.0.1 control was untouched. Tailscale's own resolver answered normally on the same box, because Tailscale exempts its own address on lo and Tunnet had no such exemption.
Move the default to 169.254.0.53. RFC 3927 reserves 169.254.0.0/24 and excludes it from link-local autoconfiguration, so nothing on the link can take it; link-local is never routed or policed by an overlay filter, and it avoids the LAN RFC1918 and Managed 10.x ranges that CGNAT was originally chosen to dodge.
Changing the default alone would only help new installs, because magic_ip is serialized into the config file. Relocate a stored contested address on load as well, with a warning naming the override. This is safe to do locally: nothing derives the resolver address and no peer needs to agree on it, unlike the mesh addresses.
Note this does NOT fix synthetic peer IPs, which synthetic_ip_for hardcodes to 100.100.0.0/16 and which both ends derive independently, so they cannot be relocated without coordination.
UNVERIFIED: the OS DNS integration has not been exercised with a link-local resolver address on a live host. systemd-resolved and the other osdns backends accept it in principle, but that needs confirming before merge.