From 1a94c309ea1a09d9d41d0bfea7fa368bcda0dd2e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 9 Nov 2022 21:04:05 -0800 Subject: [PATCH] ipn/ipnlocal: support web TLS ports other than 443 Updates tailscale/corp#7515 Change-Id: I87df50b1bc92efd1d8c538c2ad4f1222361e4d6b Signed-off-by: Brad Fitzpatrick --- ipn/ipnlocal/serve.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go index 7818de7af..614e25075 100644 --- a/ipn/ipnlocal/serve.go +++ b/ipn/ipnlocal/serve.go @@ -8,6 +8,7 @@ import ( "context" "crypto/tls" "errors" + "fmt" "io" "net" "net/http" @@ -19,6 +20,14 @@ import ( "tailscale.com/net/netutil" ) +// serveHTTPContextKey is the context.Value key for a *serveHTTPContext. +type serveHTTPContextKey struct{} + +type serveHTTPContext struct { + SrcAddr netip.AddrPort + DestPort uint16 +} + func (b *LocalBackend) HandleInterceptedTCPConn(dport uint16, srcAddr netip.AddrPort, getConn func() (net.Conn, bool), sendRST func()) { b.mu.Lock() sc := b.serveConfig @@ -43,13 +52,17 @@ func (b *LocalBackend) HandleInterceptedTCPConn(dport uint16, srcAddr netip.Addr b.logf("localbackend: getConn didn't complete from %v to port %v", srcAddr, dport) return } - - // TODO(bradfitz): look up how; sniff SNI if ambiguous hs := &http.Server{ TLSConfig: &tls.Config{ GetCertificate: b.getTLSServeCert, }, Handler: http.HandlerFunc(b.serveWebHandler), + BaseContext: func(_ net.Listener) context.Context { + return context.WithValue(context.Background(), serveHTTPContextKey{}, &serveHTTPContext{ + SrcAddr: srcAddr, + DestPort: dport, + }) + }, } hs.ServeTLS(netutil.NewOneConnListener(conn, nil), "", "") return @@ -105,9 +118,13 @@ func (b *LocalBackend) getServeHandler(r *http.Request) (_ ipn.HTTPHandlerView, return z, false } + sctx, ok := r.Context().Value(serveHTTPContextKey{}).(*serveHTTPContext) + if !ok { + b.logf("[unexpected] localbackend: no serveHTTPContext in request") + return z, false + } sni := r.TLS.ServerName - port := "443" // TODO(bradfitz): fix - key := ipn.HostPort(net.JoinHostPort(sni, port)) + key := ipn.HostPort(fmt.Sprintf("%s:%v", sni, sctx.DestPort)) b.mu.Lock() defer b.mu.Unlock()