cmd/tailscale/cli: make netcheck run even if machine lacks TLS certs

We have a fancy package for doing TLS cert validation even if the machine
doesn't have TLS certs (for LetsEncrypt only) but the CLI's netcheck command
wasn't using it.

Also, update the tlsdial's outdated package docs while here.

Updates #cleanup

Change-Id: I74b3cb645d07af4d8ae230fb39a60c809ec129ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2023-08-23 20:21:37 -07:00 committed by Brad Fitzpatrick
parent e881c1caec
commit d58ba59fd5
2 changed files with 28 additions and 8 deletions

View File

@ -21,6 +21,7 @@
"tailscale.com/net/netcheck"
"tailscale.com/net/netmon"
"tailscale.com/net/portmapper"
"tailscale.com/net/tlsdial"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
)
@ -76,7 +77,8 @@ func runNetcheck(ctx context.Context, args []string) error {
log.Printf("No DERP map from tailscaled; using default.")
}
if err != nil || noRegions {
dm, err = prodDERPMap(ctx, http.DefaultClient)
hc := &http.Client{Transport: tlsdial.NewTransport()}
dm, err = prodDERPMap(ctx, hc)
if err != nil {
return err
}

View File

@ -1,22 +1,24 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Package tlsdial originally existed to set up a tls.Config for x509
// validation, using a memory-optimized path for iOS, but then we
// moved that to the tailscale/go tree instead, so now this package
// does very little. But for now we keep it as a unified point where
// we might want to add shared policy on outgoing TLS connections from
// the 3 places in the client that connect to Tailscale (logs,
// control, DERP).
// Package tlsdial generates tls.Config values and does x509 validation of
// certs. It bakes in the LetsEncrypt roots so even if the user's machine
// doesn't have TLS roots, we can at least connect to Tailscale's LetsEncrypt
// services. It's the unified point where we can add shared policy on outgoing
// TLS connections from the three places in the client that connect to Tailscale
// (logs, control, DERP).
package tlsdial
import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"log"
"net"
"net/http"
"os"
"sync"
"sync/atomic"
@ -192,6 +194,22 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) {
}
}
// NewTransport returns a new HTTP transport that verifies TLS certs using this
// package, including its baked-in LetsEncrypt fallback roots.
func NewTransport() *http.Transport {
return &http.Transport{
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
var d tls.Dialer
d.Config = Config(host, nil)
return d.DialContext(ctx, network, addr)
},
}
}
/*
letsEncryptX1 is the LetsEncrypt X1 root: