derp/derphttp: fix DERP TLS client server name inclusion in URL form

When dialed with just an URL and no node, the recent proxy fixes caused
a regression where there was no TLS server name being included.

Updates #16222
Updates #16223

Signed-off-by: James Tucker <james@tailscale.com>
Co-Authored-by: Jordan Whited <jwhited@tailscale.com>
This commit is contained in:
James Tucker 2025-07-02 14:32:21 -07:00 committed by James Tucker
parent eb03d42fe6
commit 77d19604f4
2 changed files with 39 additions and 1 deletions

View File

@ -648,12 +648,14 @@ 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.HealthTracker, c.TLSConfig)
// node is allowed to be nil here, tlsServerName falls back to using the URL
// if node is nil.
tlsConf.ServerName = c.tlsServerName(node)
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)

View File

@ -590,3 +590,39 @@ func TestManualDial(t *testing.T) {
t.Fatalf("rc.Connect: %v", err)
}
}
func TestURLDial(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)
}
// find a valid target DERP host to test against
var hostname string
for _, reg := range dm.Regions {
for _, node := range reg.Nodes {
if !node.STUNOnly && node.CanPort80 && node.CertName == "" || node.CertName == node.HostName {
hostname = node.HostName
break
}
}
if hostname != "" {
break
}
}
netMon := netmon.NewStatic()
c, err := NewClient(key.NewNode(), "https://"+hostname+"/", t.Logf, netMon)
defer c.Close()
if err := c.Connect(context.Background()); err != nil {
t.Fatalf("rc.Connect: %v", err)
}
}