Valkey, the community-driven fork of Redis, can secure its client and replication connections using TLS, but it’s not just about enabling encryption; it’s about managing a distributed system’s trust boundaries.
Let’s see Valkey in action with TLS. We’ll set up a simple primary-replica pair where replication traffic is encrypted.
First, we need certificates. For a quick test, we can generate self-signed certificates. In a production environment, you’d use certificates signed by a trusted Certificate Authority (CA).
# Generate a CA
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=ValkeyTestCA"
# Generate a key and CSR for the primary
openssl genrsa -out primary.key 2048
openssl req -new -key primary.key -out primary.csr -subj "/CN=valkey-primary"
# Sign the primary's CSR with our CA
openssl x509 -req -in primary.csr -CA ca.crt -CAkey ca.key -days 365 -CAcreateserial -out primary.crt
# Generate a key and CSR for the replica
openssl genrsa -out replica.key 2048
openssl req -new -key replica.key -out replica.csr -subj "/CN=valkey-replica"
# Sign the replica's CSR with our CA
openssl x509 -req -in replica.csr -CA ca.crt -CAkey ca.key -days 365 -CAcreateserial -out replica.crt
Now, let’s configure the Valkey primary to use TLS for replication. We’ll place the CA certificate and the primary’s certificate/key pair on the primary server.
valkey-primary.conf:
port 6379
tls-port 6380
tls-replication yes
tls-cert-file /path/to/certs/primary.crt
tls-key-file /path/to/certs/primary.key
tls-ca-cert-file /path/to/certs/ca.crt
Start the primary Valkey instance with this configuration.
Next, configure the replica to connect to the primary using TLS for replication. The replica needs the CA certificate to verify the primary’s identity.
valkey-replica.conf:
port 6379
replicaof valkey-primary 6380 # Connect to the TLS port
tls-replication yes
tls-cert-file /path/to/certs/replica.crt
tls-key-file /path/to/certs/replica.key
tls-ca-cert-file /path/to/certs/ca.crt
Start the replica Valkey instance. If everything is set up correctly, the replica will connect to the primary’s TLS port (6380) and establish an encrypted replication stream. You can verify this by checking the INFO replication output on both servers. On the primary, you should see the replica listed with flags:replica and repl_state:connected. On the replica, master_host should be valkey-primary and master_port should be 6380.
This setup encrypts the data flowing between the primary and replica, protecting it from eavesdropping. It also provides mutual authentication if configured, ensuring that only authorized replicas can connect to the primary.
The primary challenge with TLS in distributed systems like Valkey is establishing and maintaining trust. When a server needs to connect to another (e.g., replica to primary, or client to server), it needs to verify the identity of the other party. This is typically done using certificates. A server presents its certificate, and the connecting party verifies it against a set of trusted Certificate Authorities (CAs) or by directly trusting the presented certificate. For replication, both primary and replica can be configured to use TLS, offering encryption and authentication for the data synchronization process.
The tls-replication yes directive in the Valkey configuration is what enables TLS for the replication stream. When this is set, Valkey will attempt to establish a TLS connection on the specified replicaof host and port. The tls-cert-file and tls-key-file specify the server’s own certificate and private key, which it uses to authenticate itself to the connecting party. The tls-ca-cert-file is crucial for verifying the identity of the other party. For example, when a replica connects to a primary, the replica uses the tls-ca-cert-file to validate the primary’s certificate. Conversely, the primary uses its tls-ca-cert-file to validate the replica’s certificate if tls-auth-clients yes is also enabled on the primary.
When you configure tls-replication yes, Valkey doesn’t just encrypt the data within the replication protocol. It negotiates a full TLS handshake before any replication commands (like PSYNC or REPLCONF) are exchanged. This means that the entire communication channel for replication is secured from the very beginning. If the TLS handshake fails for any reason – certificate mismatch, expired certificate, untrusted CA, or an unsupported cipher suite – the replication connection will not be established.
A common point of confusion is when to use tls-port versus the standard port. The port directive defines the non-TLS listening port, while tls-port defines the TLS-enabled listening port. For replication, you point the replicaof directive to the hostname and the TLS port (e.g., replicaof valkey-primary 6380) if the primary is configured to listen for replication over TLS. If you only have port configured and tls-replication yes, Valkey might try to upgrade the existing connection or require a separate TLS port. It’s best practice to explicitly define a tls-port for TLS-enabled services to avoid ambiguity.
The tls-auth-clients yes directive on the primary server adds an extra layer of security. When enabled, the primary will require connecting replicas (or clients on a TLS-enabled client port) to present their own client certificates. The primary then verifies these client certificates against the CA specified in its tls-ca-cert-file. This ensures that not only can the primary verify the identity of connecting entities, but connecting entities can also be verified by the primary, creating a mutual TLS (mTLS) setup. Without tls-auth-clients yes, the primary trusts any replica that can successfully connect to its TLS port and present a certificate that passes its CA validation.
The most surprising thing about Valkey’s TLS configuration is that the tls-ca-cert-file on a server is used to validate the other party’s certificate, not its own. You point tls-cert-file and tls-key-file to your server’s identity, but you point tls-ca-cert-file to the CA that signed the identity of the server you expect to connect to. This means the primary’s tls-ca-cert-file is used to trust replicas (if mTLS is on), and the replica’s tls-ca-cert-file is used to trust the primary.
After successfully enabling TLS for replication, the next challenge will be configuring TLS for client connections.