From 3496d62ed3de14dd1360f0ef09dd0ee2b48f8033 Mon Sep 17 00:00:00 2001 From: Tom DNetto Date: Tue, 7 Nov 2023 15:45:46 -0800 Subject: [PATCH] ipn/ipnlocal: add empty address to the app-connector localNets set App connectors handle DNS requests for app domains over PeerAPI, 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. 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. See: https://github.com/tailscale/corp/issues/11961 for more information. Signed-off-by: Tom DNetto Updates: ENG-2405 --- ipn/ipnlocal/local.go | 12 ++++++++++++ ipn/ipnlocal/peerapi.go | 7 +++++++ 2 files changed, 19 insertions(+) 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