From c3ef6fb4ee2a8d423d85e3e0b2abcada9319e2c9 Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Wed, 19 Apr 2023 15:23:26 -0700 Subject: [PATCH] ipn/ipnlocal: handle masquerade addresses in PeerAPI Without this, the peer fails to do anything over the PeerAPI if it has a masquerade address. ``` Apr 19 13:58:15 hydrogen tailscaled[6696]: peerapi: invalid request from :58334: 100.64.0.1/32 not found in self addresses ``` Updates #8020 Signed-off-by: Maisem Ali --- ipn/ipnlocal/peerapi.go | 15 ++++++++++++--- tstest/integration/integration_test.go | 8 ++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index d28206418..fa749d995 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -605,6 +605,16 @@ func (h *peerAPIHandler) logf(format string, a ...any) { h.ps.b.logf("peerapi: "+format, a...) } +// isAddressValid reports whether addr is a valid destination address for this +// node originating from the peer. +func (h *peerAPIHandler) isAddressValid(addr netip.Addr) bool { + if h.peerNode.SelfNodeV4MasqAddrForThisPeer != nil { + return *h.peerNode.SelfNodeV4MasqAddrForThisPeer == addr + } + pfx := netip.PrefixFrom(addr, addr.BitLen()) + return slices.Contains(h.selfNode.Addresses, pfx) +} + func (h *peerAPIHandler) validateHost(r *http.Request) error { if r.Host == "peer" { return nil @@ -613,9 +623,8 @@ func (h *peerAPIHandler) validateHost(r *http.Request) error { if err != nil { return err } - hostIPPfx := netip.PrefixFrom(ap.Addr(), ap.Addr().BitLen()) - if !slices.Contains(h.selfNode.Addresses, hostIPPfx) { - return fmt.Errorf("%v not found in self addresses", hostIPPfx) + if !h.isAddressValid(ap.Addr()) { + return fmt.Errorf("%v not found in self addresses", ap.Addr()) } return nil } diff --git a/tstest/integration/integration_test.go b/tstest/integration/integration_test.go index e790d0454..486b89492 100644 --- a/tstest/integration/integration_test.go +++ b/tstest/integration/integration_test.go @@ -601,9 +601,17 @@ func TestNATPing(t *testing.T) { t.Fatal(err) } + if err := n1.Tailscale("ping", "-peerapi", tc.n1SeesN2IP.String()).Run(); err != nil { + t.Fatal(err) + } + if err := n2.Tailscale("ping", tc.n2SeesN1IP.String()).Run(); err != nil { t.Fatal(err) } + + if err := n2.Tailscale("ping", "-peerapi", tc.n2SeesN1IP.String()).Run(); err != nil { + t.Fatal(err) + } }) } }