Skip to content

Commit 0cc1b2f

Browse files
committed
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]>
1 parent 3a49b74 commit 0cc1b2f

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

cmd/derper/ace.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
// TODO: docs about all this
5+
6+
package main
7+
8+
import (
9+
"errors"
10+
"fmt"
11+
"net"
12+
"net/http"
13+
"strings"
14+
15+
"tailscale.com/derp"
16+
"tailscale.com/net/connectproxy"
17+
)
18+
19+
// serveConnect handles a CONNECT request for ACE support.
20+
func serveConnect(s *derp.Server, w http.ResponseWriter, r *http.Request) {
21+
if !*flagACEEnabled {
22+
http.Error(w, "CONNECT not enabled", http.StatusForbidden)
23+
return
24+
}
25+
if r.TLS == nil {
26+
// This should already be enforced by the caller of serveConnect, but
27+
// double check.
28+
http.Error(w, "CONNECT requires TLS", http.StatusForbidden)
29+
return
30+
}
31+
32+
ch := &connectproxy.Handler{
33+
Check: func(hostPort string) error {
34+
host, port, err := net.SplitHostPort(hostPort)
35+
if err != nil {
36+
return err
37+
}
38+
if port != "443" {
39+
return fmt.Errorf("only port 443 is allowed")
40+
}
41+
// TODO(bradfitz): make policy configurable from flags and/or come
42+
// from local tailscaled nodeAttrs
43+
if !strings.HasSuffix(host, ".tailscale.com") || strings.Contains(host, "derp") {
44+
return errors.New("bad host")
45+
}
46+
return nil
47+
},
48+
}
49+
ch.ServeHTTP(w, r)
50+
}

cmd/derper/depaware.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
105105
tailscale.com/kube/kubetypes from tailscale.com/envknob
106106
tailscale.com/metrics from tailscale.com/cmd/derper+
107107
tailscale.com/net/bakedroots from tailscale.com/net/tlsdial
108+
tailscale.com/net/connectproxy from tailscale.com/cmd/derper
108109
tailscale.com/net/dnscache from tailscale.com/derp/derphttp
109110
tailscale.com/net/ktimeout from tailscale.com/cmd/derper
110111
tailscale.com/net/netaddr from tailscale.com/ipn+

cmd/derper/derper.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ var (
9191
tcpUserTimeout = flag.Duration("tcp-user-timeout", 15*time.Second, "TCP user timeout")
9292
// tcpWriteTimeout is the timeout for writing to client TCP connections. It does not apply to mesh connections.
9393
tcpWriteTimeout = flag.Duration("tcp-write-timeout", derp.DefaultTCPWiteTimeout, "TCP write timeout; 0 results in no timeout being set on writes")
94+
95+
// ACE
96+
flagACEEnabled = flag.Bool("ace", false, "whether to enable embedded ACE server [experimental + in-development as of 2025-09-12; not yet documented]")
9497
)
9598

9699
var (
@@ -373,6 +376,11 @@ func main() {
373376
tlsRequestVersion.Add(label, 1)
374377
tlsActiveVersion.Add(label, 1)
375378
defer tlsActiveVersion.Add(label, -1)
379+
380+
if r.Method == "CONNECT" {
381+
serveConnect(s, w, r)
382+
return
383+
}
376384
}
377385

378386
mux.ServeHTTP(w, r)

0 commit comments

Comments
 (0)