From e9c851b04bdf67bf78d7928445005a6fa515403b Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 16 Nov 2022 11:38:25 -0800 Subject: [PATCH] ipn/ipnlocal: also accept service IP IPv6 literal in brackets for quad100 The fix in 4fc8538e2 was sufficient for IPv6. Browsers (can?) send the IPv6 literal, even without a port number, in brackets. Updates tailscale/corp#7948 Change-Id: I0e429d3de4df8429152c12f251ab140b0c8f6b77 Signed-off-by: Brad Fitzpatrick --- ipn/ipnlocal/local.go | 15 ++++++++++++--- net/tsaddr/tsaddr.go | 7 ++++++- net/tsaddr/tsaddr_test.go | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 8d3ab6d3d..147c9810e 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -3925,6 +3925,17 @@ func (b *LocalBackend) HandleQuad100Port80Conn(c net.Conn) { s.Serve(netutil.NewOneConnListener(c, nil)) } +func validQuad100Host(h string) bool { + switch h { + case "", + tsaddr.TailscaleServiceIPString, + tsaddr.TailscaleServiceIPv6String, + "[" + tsaddr.TailscaleServiceIPv6String + "]": + return true + } + return false +} + func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Content-Security-Policy", "default-src 'self';") @@ -3932,9 +3943,7 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } - switch r.Host { - case "", tsaddr.TailscaleServiceIP().String(), tsaddr.TailscaleServiceIPv6().String(): - default: + if !validQuad100Host(r.Host) { http.Error(w, "bad request", http.StatusBadRequest) return } diff --git a/net/tsaddr/tsaddr.go b/net/tsaddr/tsaddr.go index bd9cdddc5..706c6d793 100644 --- a/net/tsaddr/tsaddr.go +++ b/net/tsaddr/tsaddr.go @@ -57,10 +57,15 @@ func TailscaleServiceIP() netip.Addr { // // For IPv4, use TailscaleServiceIP. func TailscaleServiceIPv6() netip.Addr { - serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, "fd7a:115c:a1e0::53/128") }) + serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, TailscaleServiceIPv6String+"/128") }) return serviceIPv6.v.Addr() } +const ( + TailscaleServiceIPString = "100.100.100.100" + TailscaleServiceIPv6String = "fd7a:115c:a1e0::53" +) + // IsTailscaleIP reports whether ip is an IP address in a range that // Tailscale assigns from. func IsTailscaleIP(ip netip.Addr) bool { diff --git a/net/tsaddr/tsaddr_test.go b/net/tsaddr/tsaddr_test.go index 812475ac1..60d79f42a 100644 --- a/net/tsaddr/tsaddr_test.go +++ b/net/tsaddr/tsaddr_test.go @@ -32,12 +32,26 @@ func TestInCrostiniRange(t *testing.T) { } } +func TestTailscaleServiceIP(t *testing.T) { + got := TailscaleServiceIP().String() + want := "100.100.100.100" + if got != want { + t.Errorf("got %q; want %q", got, want) + } + if TailscaleServiceIPString != want { + t.Error("TailscaleServiceIPString is not consistent") + } +} + func TestTailscaleServiceIPv6(t *testing.T) { got := TailscaleServiceIPv6().String() want := "fd7a:115c:a1e0::53" if got != want { t.Errorf("got %q; want %q", got, want) } + if TailscaleServiceIPv6String != want { + t.Error("TailscaleServiceIPv6String is not consistent") + } } func TestChromeOSVMRange(t *testing.T) {