mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 22:47:30 +00:00
net/tlsdial: fix TLS cert validation of HTTPS proxies
If you had HTTPS_PROXY=https://some-valid-cert.example.com running a CONNECT proxy, we should've been able to do a TLS CONNECT request to e.g. controlplane.tailscale.com:443 through that, and I'm pretty sure it used to work, but refactorings and lack of integration tests made it regress. It probably regressed when we added the baked-in LetsEncrypt root cert validation fallback code, which was testing against the wrong hostname (the ultimate one, not the one which we were being asked to validate) Fixes #16222 Change-Id: If014e395f830e2f87f056f588edacad5c15e91bc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
4979ce7a94
commit
e92eb6b17b
@@ -647,12 +647,13 @@ func (c *Client) dialRegion(ctx context.Context, reg *tailcfg.DERPRegion) (net.C
|
||||
}
|
||||
|
||||
func (c *Client) tlsClient(nc net.Conn, node *tailcfg.DERPNode) *tls.Conn {
|
||||
tlsConf := tlsdial.Config(c.tlsServerName(node), c.HealthTracker, c.TLSConfig)
|
||||
tlsConf := tlsdial.Config(c.HealthTracker, c.TLSConfig)
|
||||
if node != nil {
|
||||
if node.InsecureForTests {
|
||||
tlsConf.InsecureSkipVerify = true
|
||||
tlsConf.VerifyConnection = nil
|
||||
}
|
||||
tlsConf.ServerName = c.tlsServerName(node)
|
||||
if node.CertName != "" {
|
||||
if suf, ok := strings.CutPrefix(node.CertName, "sha256-raw:"); ok {
|
||||
tlsdial.SetConfigExpectedCertHash(tlsConf, suf)
|
||||
|
@@ -7,10 +7,14 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -19,6 +23,7 @@ import (
|
||||
"tailscale.com/derp"
|
||||
"tailscale.com/net/netmon"
|
||||
"tailscale.com/net/netx"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
@@ -556,3 +561,32 @@ func TestNotifyError(t *testing.T) {
|
||||
t.Fatalf("context done before receiving error: %v", ctx.Err())
|
||||
}
|
||||
}
|
||||
|
||||
var liveNetworkTest = flag.Bool("live-net-tests", false, "run live network tests")
|
||||
|
||||
func TestManualDial(t *testing.T) {
|
||||
if !*liveNetworkTest {
|
||||
t.Skip("skipping live network test without --live-net-tests")
|
||||
}
|
||||
dm := &tailcfg.DERPMap{}
|
||||
res, err := http.Get("https://controlplane.tailscale.com/derpmap/default")
|
||||
if err != nil {
|
||||
t.Fatalf("fetching DERPMap: %v", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if err := json.NewDecoder(res.Body).Decode(dm); err != nil {
|
||||
t.Fatalf("decoding DERPMap: %v", err)
|
||||
}
|
||||
|
||||
region := slices.Sorted(maps.Keys(dm.Regions))[0]
|
||||
|
||||
netMon := netmon.NewStatic()
|
||||
rc := NewRegionClient(key.NewNode(), t.Logf, netMon, func() *tailcfg.DERPRegion {
|
||||
return dm.Regions[region]
|
||||
})
|
||||
defer rc.Close()
|
||||
|
||||
if err := rc.Connect(context.Background()); err != nil {
|
||||
t.Fatalf("rc.Connect: %v", err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user