Просмотр исходного кода

cmd/derper: add start of ACE support

Updates tailscale/corp#32168
Updates tailscale/corp#32226

Change-Id: Ia46abcaa09dcfd53bf8d4699909537bacf84d57a
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 5 месяцев назад
Родитель
Сommit
0cc1b2ff76
3 измененных файлов с 59 добавлено и 0 удалено
  1. 50 0
      cmd/derper/ace.go
  2. 1 0
      cmd/derper/depaware.txt
  3. 8 0
      cmd/derper/derper.go

+ 50 - 0
cmd/derper/ace.go

@@ -0,0 +1,50 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// TODO: docs about all this
+
+package main
+
+import (
+	"errors"
+	"fmt"
+	"net"
+	"net/http"
+	"strings"
+
+	"tailscale.com/derp"
+	"tailscale.com/net/connectproxy"
+)
+
+// serveConnect handles a CONNECT request for ACE support.
+func serveConnect(s *derp.Server, w http.ResponseWriter, r *http.Request) {
+	if !*flagACEEnabled {
+		http.Error(w, "CONNECT not enabled", http.StatusForbidden)
+		return
+	}
+	if r.TLS == nil {
+		// This should already be enforced by the caller of serveConnect, but
+		// double check.
+		http.Error(w, "CONNECT requires TLS", http.StatusForbidden)
+		return
+	}
+
+	ch := &connectproxy.Handler{
+		Check: func(hostPort string) error {
+			host, port, err := net.SplitHostPort(hostPort)
+			if err != nil {
+				return err
+			}
+			if port != "443" {
+				return fmt.Errorf("only port 443 is allowed")
+			}
+			// TODO(bradfitz): make policy configurable from flags and/or come
+			// from local tailscaled nodeAttrs
+			if !strings.HasSuffix(host, ".tailscale.com") || strings.Contains(host, "derp") {
+				return errors.New("bad host")
+			}
+			return nil
+		},
+	}
+	ch.ServeHTTP(w, r)
+}

+ 1 - 0
cmd/derper/depaware.txt

@@ -105,6 +105,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
         tailscale.com/kube/kubetypes                                 from tailscale.com/envknob
         tailscale.com/metrics                                        from tailscale.com/cmd/derper+
         tailscale.com/net/bakedroots                                 from tailscale.com/net/tlsdial
+        tailscale.com/net/connectproxy                               from tailscale.com/cmd/derper
         tailscale.com/net/dnscache                                   from tailscale.com/derp/derphttp
         tailscale.com/net/ktimeout                                   from tailscale.com/cmd/derper
         tailscale.com/net/netaddr                                    from tailscale.com/ipn+

+ 8 - 0
cmd/derper/derper.go

@@ -91,6 +91,9 @@ var (
 	tcpUserTimeout = flag.Duration("tcp-user-timeout", 15*time.Second, "TCP user timeout")
 	// tcpWriteTimeout is the timeout for writing to client TCP connections. It does not apply to mesh connections.
 	tcpWriteTimeout = flag.Duration("tcp-write-timeout", derp.DefaultTCPWiteTimeout, "TCP write timeout; 0 results in no timeout being set on writes")
+
+	// ACE
+	flagACEEnabled = flag.Bool("ace", false, "whether to enable embedded ACE server [experimental + in-development as of 2025-09-12; not yet documented]")
 )
 
 var (
@@ -373,6 +376,11 @@ func main() {
 				tlsRequestVersion.Add(label, 1)
 				tlsActiveVersion.Add(label, 1)
 				defer tlsActiveVersion.Add(label, -1)
+
+				if r.Method == "CONNECT" {
+					serveConnect(s, w, r)
+					return
+				}
 			}
 
 			mux.ServeHTTP(w, r)