Browse Source

cmd/derper: add --socket flag to change unix socket path to tailscaled

Fixes #10359

Change-Id: Ide49941c486d29856841016686827316878c9433
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 1 year ago
parent
commit
83c104652d
2 changed files with 17 additions and 4 deletions
  1. 4 0
      cmd/derper/derper.go
  2. 13 4
      derp/derp_server.go

+ 4 - 0
cmd/derper/derper.go

@@ -71,10 +71,13 @@ var (
 	secretsCacheDir = flag.String("secrets-cache-dir", defaultSetecCacheDir(), "directory to cache setec secrets in (required if --secrets-url is set)")
 	bootstrapDNS    = flag.String("bootstrap-dns-names", "", "optional comma-separated list of hostnames to make available at /bootstrap-dns")
 	unpublishedDNS  = flag.String("unpublished-bootstrap-dns-names", "", "optional comma-separated list of hostnames to make available at /bootstrap-dns and not publish in the list. If an entry contains a slash, the second part names a DNS record to poll for its TXT record with a `0` to `100` value for rollout percentage.")
+
 	verifyClients   = flag.Bool("verify-clients", false, "verify clients to this DERP server through a local tailscaled instance.")
 	verifyClientURL = flag.String("verify-client-url", "", "if non-empty, an admission controller URL for permitting client connections; see tailcfg.DERPAdmitClientRequest")
 	verifyFailOpen  = flag.Bool("verify-client-url-fail-open", true, "whether we fail open if --verify-client-url is unreachable")
 
+	socket = flag.String("socket", "", "optional alternate path to tailscaled socket (only relevant when using --verify-clients)")
+
 	acceptConnLimit = flag.Float64("accept-connection-limit", math.Inf(+1), "rate limit for accepting new connection")
 	acceptConnBurst = flag.Int("accept-connection-burst", math.MaxInt, "burst limit for accepting new connection")
 
@@ -192,6 +195,7 @@ func main() {
 
 	s := derp.NewServer(cfg.PrivateKey, log.Printf)
 	s.SetVerifyClient(*verifyClients)
+	s.SetTailscaledSocketPath(*socket)
 	s.SetVerifyClientURL(*verifyClientURL)
 	s.SetVerifyClientURLFailOpen(*verifyFailOpen)
 	s.SetTCPWriteTimeout(*tcpWriteTimeout)

+ 13 - 4
derp/derp_server.go

@@ -137,6 +137,7 @@ type Server struct {
 	metaCert    []byte // the encoded x509 cert to send after LetsEncrypt cert+intermediate
 	dupPolicy   dupPolicy
 	debug       bool
+	localClient local.Client
 
 	// Counters:
 	packetsSent, bytesSent     expvar.Int
@@ -485,6 +486,16 @@ func (s *Server) SetVerifyClientURLFailOpen(v bool) {
 	s.verifyClientsURLFailOpen = v
 }
 
+// SetTailscaledSocketPath sets the unix socket path to use to talk to
+// tailscaled if client verification is enabled.
+//
+// If unset or set to the empty string, the default path for the operating
+// system is used.
+func (s *Server) SetTailscaledSocketPath(path string) {
+	s.localClient.Socket = path
+	s.localClient.UseSocketOnly = path != ""
+}
+
 // SetTCPWriteTimeout sets the timeout for writing to connected clients.
 // This timeout does not apply to mesh connections.
 // Defaults to 2 seconds.
@@ -1320,8 +1331,6 @@ func (c *sclient) requestMeshUpdate() {
 	}
 }
 
-var localClient local.Client
-
 // isMeshPeer reports whether the client is a trusted mesh peer
 // node in the DERP region.
 func (s *Server) isMeshPeer(info *clientInfo) bool {
@@ -1340,7 +1349,7 @@ func (s *Server) verifyClient(ctx context.Context, clientKey key.NodePublic, inf
 
 	// tailscaled-based verification:
 	if s.verifyClientsLocalTailscaled {
-		_, err := localClient.WhoIsNodeKey(ctx, clientKey)
+		_, err := s.localClient.WhoIsNodeKey(ctx, clientKey)
 		if err == tailscale.ErrPeerNotFound {
 			return fmt.Errorf("peer %v not authorized (not found in local tailscaled)", clientKey)
 		}
@@ -2240,7 +2249,7 @@ func (s *Server) ConsistencyCheck() error {
 func (s *Server) checkVerifyClientsLocalTailscaled() error {
 	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 	defer cancel()
-	status, err := localClient.StatusWithoutPeers(ctx)
+	status, err := s.localClient.StatusWithoutPeers(ctx)
 	if err != nil {
 		return fmt.Errorf("localClient.Status: %w", err)
 	}