mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Fix resetting TLS name from solicited remotes
In +Go 1.20, the x509.HostnameError changed to be wrapped in a tls.CertificateVerificationError so sometimes the name would not be reset causing tests to be extra flaky. Signed-off-by: Waldemar Quevedo <wally@nats.io>
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -33,7 +34,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/klauspost/compress/s2"
|
"github.com/klauspost/compress/s2"
|
||||||
|
|
||||||
"github.com/nats-io/jwt/v2"
|
"github.com/nats-io/jwt/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -5502,7 +5502,10 @@ func (c *client) doTLSHandshake(typ string, solicit bool, url *url.URL, tlsConfi
|
|||||||
if solicit {
|
if solicit {
|
||||||
// Based on type of error, possibly clear the saved tlsName
|
// Based on type of error, possibly clear the saved tlsName
|
||||||
// See: https://github.com/nats-io/nats-server/issues/1256
|
// See: https://github.com/nats-io/nats-server/issues/1256
|
||||||
if _, ok := err.(x509.HostnameError); ok {
|
// NOTE: As of Go 1.20, the HostnameError is wrapped so cannot
|
||||||
|
// type assert to check directly.
|
||||||
|
var hostnameErr x509.HostnameError
|
||||||
|
if errors.As(err, &hostnameErr) {
|
||||||
if host == tlsName {
|
if host == tlsName {
|
||||||
resetTLSName = true
|
resetTLSName = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -605,89 +605,96 @@ func TestGatewayTLSMixedIPAndDNS(t *testing.T) {
|
|||||||
server.SetGatewaysSolicitDelay(5 * time.Millisecond)
|
server.SetGatewaysSolicitDelay(5 * time.Millisecond)
|
||||||
defer server.ResetGatewaysSolicitDelay()
|
defer server.ResetGatewaysSolicitDelay()
|
||||||
|
|
||||||
confA1 := createConfFile(t, []byte(`
|
// Run this test extra times to make sure not flaky since it
|
||||||
listen: 127.0.0.1:-1
|
// on solicit time.
|
||||||
gateway {
|
for i := 0; i < 10; i++ {
|
||||||
name: "A"
|
t.Run("", func(t *testing.T) {
|
||||||
listen: "127.0.0.1:-1"
|
confA1 := createConfFile(t, []byte(`
|
||||||
tls {
|
listen: 127.0.0.1:-1
|
||||||
cert_file: "./configs/certs/server-iponly.pem"
|
server_name: A1
|
||||||
key_file: "./configs/certs/server-key-iponly.pem"
|
gateway {
|
||||||
ca_file: "./configs/certs/ca.pem"
|
name: "A"
|
||||||
timeout: 2
|
listen: "127.0.0.1:-1"
|
||||||
|
tls {
|
||||||
|
cert_file: "./configs/certs/server-iponly.pem"
|
||||||
|
key_file: "./configs/certs/server-key-iponly.pem"
|
||||||
|
ca_file: "./configs/certs/ca.pem"
|
||||||
|
timeout: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
cluster {
|
||||||
cluster {
|
listen: "127.0.0.1:-1"
|
||||||
listen: "127.0.0.1:-1"
|
}`))
|
||||||
}
|
srvA1, optsA1 := RunServerWithConfig(confA1)
|
||||||
`))
|
defer srvA1.Shutdown()
|
||||||
srvA1, optsA1 := RunServerWithConfig(confA1)
|
|
||||||
defer srvA1.Shutdown()
|
|
||||||
|
|
||||||
confA2Template := `
|
confA2Template := `
|
||||||
listen: 127.0.0.1:-1
|
listen: 127.0.0.1:-1
|
||||||
gateway {
|
server_name: A2
|
||||||
name: "A"
|
gateway {
|
||||||
listen: "localhost:-1"
|
name: "A"
|
||||||
tls {
|
listen: "localhost:-1"
|
||||||
cert_file: "./configs/certs/server-cert.pem"
|
tls {
|
||||||
key_file: "./configs/certs/server-key.pem"
|
cert_file: "./configs/certs/server-cert.pem"
|
||||||
ca_file: "./configs/certs/ca.pem"
|
key_file: "./configs/certs/server-key.pem"
|
||||||
timeout: 2
|
ca_file: "./configs/certs/ca.pem"
|
||||||
|
timeout: 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
cluster {
|
||||||
cluster {
|
listen: "127.0.0.1:-1"
|
||||||
listen: "127.0.0.1:-1"
|
routes [
|
||||||
routes [
|
"nats://%s:%d"
|
||||||
"nats://%s:%d"
|
]
|
||||||
]
|
}`
|
||||||
}
|
confA2 := createConfFile(t, []byte(fmt.Sprintf(confA2Template,
|
||||||
`
|
optsA1.Cluster.Host, optsA1.Cluster.Port)))
|
||||||
confA2 := createConfFile(t, []byte(fmt.Sprintf(confA2Template,
|
srvA2, optsA2 := RunServerWithConfig(confA2)
|
||||||
optsA1.Cluster.Host, optsA1.Cluster.Port)))
|
defer srvA2.Shutdown()
|
||||||
srvA2, optsA2 := RunServerWithConfig(confA2)
|
|
||||||
defer srvA2.Shutdown()
|
|
||||||
|
|
||||||
checkClusterFormed(t, srvA1, srvA2)
|
checkClusterFormed(t, srvA1, srvA2)
|
||||||
|
|
||||||
// Create a GW connection to cluster "A". Don't use the helper since we need verification etc.
|
// Create a GW connection to cluster "A". Don't use the helper since we need verification etc.
|
||||||
o := DefaultTestOptions
|
o := DefaultTestOptions
|
||||||
o.Port = -1
|
o.Port = -1
|
||||||
o.Gateway.Name = "B"
|
o.ServerName = "B1"
|
||||||
o.Gateway.Host = "127.0.0.1"
|
o.Gateway.Name = "B"
|
||||||
o.Gateway.Port = -1
|
o.Gateway.Host = "127.0.0.1"
|
||||||
|
o.Gateway.Port = -1
|
||||||
|
|
||||||
tc := &server.TLSConfigOpts{}
|
tc := &server.TLSConfigOpts{}
|
||||||
tc.CertFile = "./configs/certs/server-cert.pem"
|
tc.CertFile = "./configs/certs/server-cert.pem"
|
||||||
tc.KeyFile = "./configs/certs/server-key.pem"
|
tc.KeyFile = "./configs/certs/server-key.pem"
|
||||||
tc.CaFile = "./configs/certs/ca.pem"
|
tc.CaFile = "./configs/certs/ca.pem"
|
||||||
tc.Timeout = 2.0
|
tc.Timeout = 2.0
|
||||||
tlsConfig, err := server.GenTLSConfig(tc)
|
tlsConfig, err := server.GenTLSConfig(tc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error generating TLS config: %v", err)
|
t.Fatalf("Error generating TLS config: %v", err)
|
||||||
|
}
|
||||||
|
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
|
tlsConfig.RootCAs = tlsConfig.ClientCAs
|
||||||
|
|
||||||
|
o.Gateway.TLSConfig = tlsConfig.Clone()
|
||||||
|
|
||||||
|
rurl, _ := url.Parse(fmt.Sprintf("nats://%s:%d", optsA2.Gateway.Host, optsA2.Gateway.Port))
|
||||||
|
remote := &server.RemoteGatewayOpts{Name: "A", URLs: []*url.URL{rurl}}
|
||||||
|
remote.TLSConfig = tlsConfig.Clone()
|
||||||
|
o.Gateway.Gateways = []*server.RemoteGatewayOpts{remote}
|
||||||
|
|
||||||
|
srvB := RunServer(&o)
|
||||||
|
defer srvB.Shutdown()
|
||||||
|
|
||||||
|
waitForOutboundGateways(t, srvB, 1, 10*time.Second)
|
||||||
|
waitForOutboundGateways(t, srvA1, 1, 10*time.Second)
|
||||||
|
waitForOutboundGateways(t, srvA2, 1, 10*time.Second)
|
||||||
|
|
||||||
|
// Now kill off srvA2 and force serverB to connect to srvA1.
|
||||||
|
srvA2.Shutdown()
|
||||||
|
|
||||||
|
// Make sure this works.
|
||||||
|
waitForOutboundGateways(t, srvB, 1, 30*time.Second)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
|
||||||
tlsConfig.RootCAs = tlsConfig.ClientCAs
|
|
||||||
|
|
||||||
o.Gateway.TLSConfig = tlsConfig.Clone()
|
|
||||||
|
|
||||||
rurl, _ := url.Parse(fmt.Sprintf("nats://%s:%d", optsA2.Gateway.Host, optsA2.Gateway.Port))
|
|
||||||
remote := &server.RemoteGatewayOpts{Name: "A", URLs: []*url.URL{rurl}}
|
|
||||||
remote.TLSConfig = tlsConfig.Clone()
|
|
||||||
o.Gateway.Gateways = []*server.RemoteGatewayOpts{remote}
|
|
||||||
|
|
||||||
srvB := RunServer(&o)
|
|
||||||
defer srvB.Shutdown()
|
|
||||||
|
|
||||||
waitForOutboundGateways(t, srvB, 1, 10*time.Second)
|
|
||||||
waitForOutboundGateways(t, srvA1, 1, 10*time.Second)
|
|
||||||
waitForOutboundGateways(t, srvA2, 1, 10*time.Second)
|
|
||||||
|
|
||||||
// Now kill off srvA2 and force serverB to connect to srvA1.
|
|
||||||
srvA2.Shutdown()
|
|
||||||
|
|
||||||
// Make sure this works.
|
|
||||||
waitForOutboundGateways(t, srvB, 1, 10*time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGatewayAdvertiseInCluster(t *testing.T) {
|
func TestGatewayAdvertiseInCluster(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user