diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index a0d8e6e43..9cfd345f5 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -1776,6 +1776,18 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P logNetsB.AddPrefix(r) } } + + // App connectors handle DNS requests for app domains over PeerAPI (corp#11961), + // but a safety check verifies the requesting peer has at least permission + // to send traffic to 0.0.0.0:53 (or 2000:: for IPv6) before handling the DNS + // request (see peerAPIHandler.replyToDNSQueries in peerapi.go). + // The correct filter rules are synthesized by the coordination server + // and sent down, but the address needs to be part of the 'local net' for the + // filter package to even bother checking the filter rules, so we set them here. + if prefs.AppConnector().Advertise { + localNetsB.Add(netip.MustParseAddr("0.0.0.0")) + localNetsB.Add(netip.MustParseAddr("::0")) + } } localNets, _ := localNetsB.IPSet() logNets, _ := logNetsB.IPSet() diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index 0a7471f19..d7bd88fff 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -881,6 +881,13 @@ func (h *peerAPIHandler) replyToDNSQueries() bool { // ourselves. As a proxy for autogroup:internet access, we see // if we would've accepted a packet to 0.0.0.0:53. We treat // the IP 0.0.0.0 as being "the internet". + // + // Because of the way that filter checks work, rules are only + // checked after ensuring the destination IP is part of the + // local set of IPs. An exit node has 0.0.0.0/0 so its fine, + // but an app connector explicitly adds 0.0.0.0/32 (and the + // IPv6 equivalent) to make this work (see updateFilterLocked + // in LocalBackend). f := b.filterAtomic.Load() if f == nil { return false