From 7bb7309f4c28bb77f0347f92cd958cb46bdc7e10 Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Wed, 30 Mar 2022 18:50:52 -0600 Subject: [PATCH] [FIXED] Monitoring: verify_and_map in tls{} config would break monitoring This was introduced in v2.6.6. In order to solve a config reload issue, we used tls.Config.GetConfigForClient which allowed the TLS configuration to be "refreshed" with the latest. However, in this case, the tls.Config.ClientAuth was not reset to tls.NoClientCert which we need for monitoring port. Resolves #2980 Signed-off-by: Ivan Kozlovic --- server/monitor_test.go | 12 ++++++++++++ server/server.go | 8 +++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/server/monitor_test.go b/server/monitor_test.go index 72a82c2b..f73128ab 100644 --- a/server/monitor_test.go +++ b/server/monitor_test.go @@ -4267,6 +4267,10 @@ func TestMonitorReloadTLSConfig(t *testing.T) { cert_file: '%s' key_file: '%s' ca_file: '../test/configs/certs/ca.pem' + + # Set this to make sure that it does not impact secure monitoring + # (which it did, see issue: https://github.com/nats-io/nats-server/issues/2980) + verify_and_map: true } ` conf := createConfFile(t, []byte(fmt.Sprintf(template, @@ -4312,4 +4316,12 @@ func TestMonitorReloadTLSConfig(t *testing.T) { if err := c.(*tls.Conn).Handshake(); err != nil { t.Fatalf("Error on TLS handshake: %v", err) } + + // Need to read something to see if there is a problem with the certificate or not. + var buf [64]byte + c.SetReadDeadline(time.Now().Add(250 * time.Millisecond)) + _, err = c.Read(buf[:]) + if ne, ok := err.(net.Error); !ok || !ne.Timeout() { + t.Fatalf("Error: %v", err) + } } diff --git a/server/server.go b/server/server.go index 519a057c..1056eef1 100644 --- a/server/server.go +++ b/server/server.go @@ -2254,9 +2254,11 @@ func (cl *captureHTTPServerLog) Write(p []byte) (int, error) { // we instruct the TLS handshake to ask for the tls configuration to be // used for a specific client. We don't care which client, we always use // the same TLS configuration. -func (s *Server) getTLSConfig(_ *tls.ClientHelloInfo) (*tls.Config, error) { +func (s *Server) getMonitoringTLSConfig(_ *tls.ClientHelloInfo) (*tls.Config, error) { opts := s.getOpts() - return opts.TLSConfig, nil + tc := opts.TLSConfig.Clone() + tc.ClientAuth = tls.NoClientCert + return tc, nil } // Start the monitoring server @@ -2281,7 +2283,7 @@ func (s *Server) startMonitoring(secure bool) error { } hp = net.JoinHostPort(opts.HTTPHost, strconv.Itoa(port)) config := opts.TLSConfig.Clone() - config.GetConfigForClient = s.getTLSConfig + config.GetConfigForClient = s.getMonitoringTLSConfig config.ClientAuth = tls.NoClientCert httpListener, err = tls.Listen("tcp", hp, config)