diff --git a/conf/defaults.ini b/conf/defaults.ini index f14ae8a816a..7d3d74f286e 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -923,7 +923,7 @@ cloud = AzureCloud # A customized list of Azure cloud settings and properties, used by data sources which need this information when run in non-standard azure environments # When specified, this list will replace the default cloud list of AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud -clouds_config = +clouds_config = # Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance) # If enabled, the managed identity can be used for authentication of Grafana in Azure services @@ -1206,12 +1206,14 @@ ha_redis_max_conns = 5 ha_redis_tls_enabled = false # Path to the PEM-encoded TLS client certificate file used to authenticate with the redis server. +# Required if using Mutual TLS. ha_redis_tls_cert_path = # Path to the PEM-encoded TLS private key file. Also requires the client certificate to be configured. +# Required if using Mutual TLS. ha_redis_tls_key_path = -# Path to the PEM-encoded CA certificates file. +# Path to the PEM-encoded CA certificates file. If not set, the host's root CA certificates are used. ha_redis_tls_ca_path = # Overrides the expected name of the redis server certificate. diff --git a/conf/sample.ini b/conf/sample.ini index ee38ef354eb..779800080cf 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -1132,12 +1132,14 @@ # ha_redis_tls_enabled = false # Path to the PEM-encoded TLS client certificate file used to authenticate with the redis server. +# Required if using Mutual TLS. # ha_redis_tls_cert_path = # Path to the PEM-encoded TLS private key file. Also requires the client certificate to be configured. +# Required if using Mutual TLS. # ha_redis_tls_key_path = -# Path to the PEM-encoded CA certificates file. +# Path to the PEM-encoded CA certificates file. If not set, the host's root CA certificates are used. # ha_redis_tls_ca_path = # Overrides the expected name of the redis server certificate. diff --git a/pkg/services/ngalert/notifier/redis_peer_test.go b/pkg/services/ngalert/notifier/redis_peer_test.go index a5fe2c4e13c..121c720a21d 100644 --- a/pkg/services/ngalert/notifier/redis_peer_test.go +++ b/pkg/services/ngalert/notifier/redis_peer_test.go @@ -17,7 +17,37 @@ import ( ) func TestNewRedisPeerWithTLS(t *testing.T) { - // Write client and server certificates/keys to tempDir, both issues by the same CA + // Write client and server certificates/keys to tempDir, both issued by the same CA + certPaths := createX509TestDir(t) + + // Set up tls.Config and start miniredis with server-side TLS + x509Cert, err := tls.LoadX509KeyPair(certPaths.serverCert, certPaths.serverKey) + require.NoError(t, err) + + mr, err := miniredis.RunTLS(&tls.Config{ + Certificates: []tls.Certificate{x509Cert}, + ClientAuth: tls.NoClientCert, + }) + require.NoError(t, err) + defer mr.Close() + + // Create redis peer with TLS enabled, server does + // not need to verify any client certificates + redisPeer, err := newRedisPeer(redisConfig{ + addr: mr.Addr(), + tlsEnabled: true, + tls: dstls.ClientConfig{ + CAPath: certPaths.ca, + ServerName: "localhost", + }}, log.NewNopLogger(), prometheus.NewRegistry(), time.Second*60) + require.NoError(t, err) + + ping := redisPeer.redis.Ping(context.Background()) + require.NoError(t, ping.Err()) +} + +func TestNewRedisPeerWithMutualTLS(t *testing.T) { + // Write client and server certificates/keys to tempDir, both issued by the same CA certPaths := createX509TestDir(t) // Set up tls.Config and start miniredis with server-side TLS @@ -31,6 +61,7 @@ func TestNewRedisPeerWithTLS(t *testing.T) { mr, err := miniredis.RunTLS(&tls.Config{ Certificates: []tls.Certificate{x509Cert}, ClientCAs: clientCAPool, + ClientAuth: tls.RequireAndVerifyClientCert, }) require.NoError(t, err) defer mr.Close() @@ -44,7 +75,7 @@ func TestNewRedisPeerWithTLS(t *testing.T) { KeyPath: certPaths.clientKey, CAPath: certPaths.ca, ServerName: "localhost", - }}, log.NewNopLogger(), prometheus.DefaultRegisterer, time.Second*60) + }}, log.NewNopLogger(), prometheus.NewRegistry(), time.Second*60) require.NoError(t, err) ping := redisPeer.redis.Ping(context.Background())