diff --git a/server/leafnode.go b/server/leafnode.go index 0bc9317f..47bb8087 100644 --- a/server/leafnode.go +++ b/server/leafnode.go @@ -1160,6 +1160,12 @@ func (c *client) processLeafnodeInfo(info *Info) { // So check only for non websocket connections and for configurations // where the TLS Handshake was not done first. if didSolicit && !c.flags.isSet(handshakeComplete) && !c.isWebsocket() && !remote.TLSHandshakeFirst { + // If the server requires TLS, we need to set this in the remote + // otherwise if there is no TLS configuration block for the remote, + // the solicit side will not attempt to perform the TLS handshake. + if firstINFO && info.TLSRequired { + remote.TLS = true + } if _, err := c.leafClientHandshakeIfNeeded(remote, opts); err != nil { c.mu.Unlock() return diff --git a/server/leafnode_test.go b/server/leafnode_test.go index d068d720..a9f7e4b6 100644 --- a/server/leafnode_test.go +++ b/server/leafnode_test.go @@ -4996,6 +4996,55 @@ func TestLeafNodeTLSHandshakeFirst(t *testing.T) { checkLeafNodeConnected(t, s2) } +func TestLeafNodeTLSHandshakeEvenForRemoteWithNoTLSBlock(t *testing.T) { + confHub := createConfFile(t, []byte(` + port : -1 + leafnodes : { + port : -1 + tls { + cert_file: "../test/configs/certs/server-cert.pem" + key_file: "../test/configs/certs/server-key.pem" + ca_file: "../test/configs/certs/ca.pem" + timeout: 2 + } + } + `)) + s1, o1 := RunServerWithConfig(confHub) + defer s1.Shutdown() + + tmpl2 := ` + port: -1 + leafnodes : { + port : -1 + remotes : [ + { + urls : [tls://127.0.0.1:%d] + } + ] + } + ` + confSpoke := createConfFile(t, []byte(fmt.Sprintf(tmpl2, o1.LeafNode.Port))) + s2, _ := RunServerWithConfig(confSpoke) + defer s2.Shutdown() + + l := &captureDebugLogger{dbgCh: make(chan string, 100)} + s2.SetLogger(l, true, false) + + tm := time.NewTimer(2 * time.Second) + defer tm.Stop() + for { + select { + case l := <-l.dbgCh: + if strings.Contains(l, "Starting TLS") { + // OK! + return + } + case <-tm.C: + t.Fatalf("Did not perform a TLS handshake") + } + } +} + func TestLeafNodeCompressionOptions(t *testing.T) { org := testDefaultLeafNodeCompression testDefaultLeafNodeCompression = _EMPTY_