[FIXED] LeafNode: TLS Handshake when remote does not have a tls{} block

If a leafnode remote configuration does not have a tls{} block but
connect to a hub that requires TLS, the handshake between the two
servers will fail. A simple workaround is to add in the remote
configuration an empty tls{} block.

This issue was introduced in v2.10.0 due to some refactoring in
order to support compression.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2023-09-19 19:50:50 -06:00
parent 07a887bcfc
commit 579ee3b828
2 changed files with 55 additions and 0 deletions

View File

@@ -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

View File

@@ -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_