redis tls

Posted on: 8/27/2026 Last Updated: 8/27/2026
Using redis with TLS
All Articles

TLS Support

Getting Started

Building

To build with TLS support you'll need OpenSSL development libraries (e.g. libssl-dev on Debian/Ubuntu).

To build TLS support as Redis built-in: Run make BUILD_TLS=yes.

Or to build TLS as Redis module: Run make BUILD_TLS=module.

Note that sentinel mode does not support TLS module.

Tests

To run Redis test suite with TLS, you'll need TLS support for TCL (i.e. tcl-tls package on Debian/Ubuntu).

  1. Run ./utils/gen-test-certs.sh to generate a root CA and a server certificate.

  2. Run ./runtest --tls or ./runtest-cluster --tls to run Redis and Redis Cluster tests in TLS mode.

  3. Run ./runtest --tls-module or ./runtest-cluster --tls-module to run Redis and Redis cluster tests in TLS mode with Redis module.

Running manually

To manually run a Redis server with TLS mode (assuming gen-test-certs.sh was invoked so sample certificates/keys are available):

For TLS built-in mode: ./src/redis-server --tls-port 6379 --port 0
--tls-cert-file ./tests/tls/redis.crt
--tls-key-file ./tests/tls/redis.key
--tls-ca-cert-file ./tests/tls/ca.crt

For TLS module mode: ./src/redis-server --tls-port 6379 --port 0
--tls-cert-file ./tests/tls/redis.crt
--tls-key-file ./tests/tls/redis.key
--tls-ca-cert-file ./tests/tls/ca.crt
--loadmodule src/redis-tls.so

To connect to this Redis server with redis-cli:

./src/redis-cli --tls \
    --cert ./tests/tls/redis.crt \
    --key ./tests/tls/redis.key \
    --cacert ./tests/tls/ca.crt

This will disable TCP and enable TLS on port 6379. It's also possible to have both TCP and TLS available, but you'll need to assign different ports.

To make a Replica connect to the master using TLS, use --tls-replication yes, and to make Redis Cluster use TLS across nodes use --tls-cluster yes.

Peer certificate verification

By default, Redis TLS validates only that a peer certificate chains to the trusted CA (tls-ca-cert-file / tls-ca-cert-dir) and is not expired. It does not verify that the certificate belongs to the specific peer being contacted.

Trust model and the CA assumption

This default is safe only under a dedicated, per-cluster CA: since that CA signs certificates exclusively for your own nodes, "chains to the CA" is equivalent to "is a legitimate peer". This is the recommended Redis TLS deployment model.

If you instead use a shared, organizational, or public CA, that CA also signs certificates for machines that are not part of your deployment. In that case CA validation alone is insufficient:

tls-expected-peer-name

To close this gap under a shared CA, set tls-expected-peer-name. When set, the peer certificate must additionally carry one of the configured names in its Subject Alternative Name (SAN) field (CN is used only as a fallback), verified as part of CA chain validation. Issue every node's certificate with a shared cluster-identity SAN (e.g. node.my-redis-cluster.example.com) and set this option to that name on every node; a certificate signed by the same CA but lacking the name is then rejected.

The expected name is taken from local configuration only — never from the address dialed or from any data received over the wire (such as a gossip-announced hostname), since the whole purpose is to distinguish a real peer from an impostor.

The check is enforced in both directions of server-to-server TLS:

Because a node's outbound (client) certificate is now verified by its peers, the identity SAN must be present on whichever certificate the node presents in both roles. In practice this means the SAN must be on tls-client-cert-file (used for outbound cluster/replication connections) as well as on tls-cert-file; when no separate client certificate is configured, tls-cert-file is used for both roles and only needs the SAN once. If a separate client certificate without the SAN is configured, peers will reject this node's inbound cluster-bus connections and the cluster will not form.

Notes:

TLS groups

The tls-groups option controls the OpenSSL named groups used during TLS handshakes. The value is passed directly to OpenSSL, so it accepts the syntax supported by SSL_CTX_set1_groups_list() (or the older SSL_CTX_set1_curves_list() API), for example:

tls-groups X25519:prime256v1

Redis does not filter the list, so any group name accepted by the linked OpenSSL build can be used.

The setting applies to both the server context and Redis' client context used for replication, cluster, and other server-to-server TLS connections. The client and server must have at least one group in common for the handshake to succeed.

This option requires OpenSSL 1.0.2 or newer, which provides the SSL_CTX_set1_curves_list() API used by Redis. Newer OpenSSL versions also provide the equivalent SSL_CTX_set1_groups_list() API. Building TLS support against an older OpenSSL fails with a clear compile-time error by default. To build Redis without this option, define TLS_NO_GROUPS, for example:

make BUILD_TLS=yes CFLAGS=-DTLS_NO_GROUPS

When the feature is compiled out, setting tls-groups causes TLS context configuration to fail instead of silently ignoring the requested preference.

redis-cli and redis-benchmark expose --tls-groups when built with OpenSSL support for named group configuration. When the feature is compiled out, the command-line option is not accepted, matching the behavior of other TLS options that depend on OpenSSL build capabilities.

Connections

All socket operations now go through a connection abstraction layer that hides I/O and read/write event handling from the caller.

Multi-threading I/O is supported for TLS since Redis 8.0. TLS connections are assigned to I/O threads like plain TCP connections, and each I/O thread's event loop drains any connection-level pending data (typical for TLS) via the connection abstraction layer.

Sync IO for TLS is currently implemented in a hackish way, i.e. making the socket blocking and configuring socket-level timeout. This means the timeout value may not be so accurate, and there would be a lot of syscall overhead. However I believe that getting rid of syncio completely in favor of pure async work is probably a better move than trying to fix that. For replication it would probably not be so hard. For cluster keys migration it might be more difficult, but there are probably other good reasons to improve that part anyway.

Multi-port

Consider the implications of allowing TLS to be configured on a separate port, making Redis listening on multiple ports:

  1. Startup banner port notification
  2. Proctitle
  3. How slaves announce themselves
  4. Cluster bus port calculation
Tags:
redis db tls readme