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) + } }) } }