diff --git a/server/leafnode.go b/server/leafnode.go index 9ccbf4a9..87a54b3a 100644 --- a/server/leafnode.go +++ b/server/leafnode.go @@ -407,9 +407,14 @@ func (s *Server) connectToRemoteLeafNode(remote *leafNodeCfg, firstConnect bool) // Save off the tlsName for when we use TLS and mix hostnames and IPs. IPs usually // come from the server we connect to. +// +// We used to save the name only if there was a TLSConfig or scheme equal to "tls". +// However, this was causing failures for users that did not set the scheme (and +// their remote connections did not have a tls{} block). +// We now save the host name regardless in case the remote returns an INFO indicating +// that TLS is required. func (cfg *leafNodeCfg) saveTLSHostname(u *url.URL) { - isTLS := cfg.TLSConfig != nil || u.Scheme == "tls" - if isTLS && cfg.tlsName == "" && net.ParseIP(u.Hostname()) == nil { + if cfg.tlsName == _EMPTY_ && net.ParseIP(u.Hostname()) == nil { cfg.tlsName = u.Hostname() } } diff --git a/server/leafnode_test.go b/server/leafnode_test.go index 472117fa..9c389d70 100644 --- a/server/leafnode_test.go +++ b/server/leafnode_test.go @@ -953,6 +953,51 @@ func TestLeafCloseTLSConnection(t *testing.T) { ch <- true } +func TestLeafCloseTLSSaveName(t *testing.T) { + opts := DefaultOptions() + opts.LeafNode.Host = "127.0.0.1" + opts.LeafNode.Port = -1 + tc := &TLSConfigOpts{ + CertFile: "../test/configs/certs/server-noip.pem", + KeyFile: "../test/configs/certs/server-key-noip.pem", + Insecure: true, + } + tlsConf, err := GenTLSConfig(tc) + if err != nil { + t.Fatalf("Error generating tls config: %v", err) + } + opts.LeafNode.TLSConfig = tlsConf + s := RunServer(opts) + defer s.Shutdown() + + lo := DefaultOptions() + u, _ := url.Parse(fmt.Sprintf("nats://localhost:%d", opts.LeafNode.Port)) + lo.LeafNode.Remotes = []*RemoteLeafOpts{{URLs: []*url.URL{u}}} + lo.LeafNode.ReconnectInterval = 15 * time.Millisecond + ln := RunServer(lo) + defer ln.Shutdown() + + // We know connection will fail, but it should not fail because of error such as: + // "cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs" + // This would mean that we are not saving the hostname to use during the TLS handshake. + + le := &captureErrorLogger{errCh: make(chan string, 100)} + ln.SetLogger(le, false, false) + + tm := time.NewTimer(time.Second) + var done bool + for !done { + select { + case err := <-le.errCh: + if strings.Contains(err, "doesn't contain any IP SANs") { + t.Fatalf("Got this error: %q", err) + } + case <-tm.C: + done = true + } + } +} + func TestLeafNodeRemoteWrongPort(t *testing.T) { for _, test1 := range []struct { name string