Redis TLS — How to get and renew Redis TLS certificates — Practical Zero Trust

Redis TLS — Practical Zero Trust

How to get and renew Redis TLS certificates

Written September 20, 2021

Zero Trust or BeyondProd approaches require authenticated and encrypted communications everywhere. TLS is the cryptographic protocol that powers encryption for all your technologies. For TLS, you need certificates. This practitioner's tutorial provides instructions for automating RedisTLS certificate renewal and enabling server-side encryption.

Create a private key and request a certificate

Before you can configure Redis TLS, you will need a certificate issued by a trusted certificate authority (CA). If you already have a certificate, private key, and CA root certificate from your organization's existing CA, you can skip to the Redis TLS configuration section below. If you need to generate a certificate, you can:

Use a free hosted Smallstep Certificate Manager authority

Roll your own with open source step-ca

This tutorial is designed for private networks, not publicly trusted websites or endpoints. If you are looking to automate certificates for public websites, servers, or endpoints, we recommend using Let's Encrypt and the ACME instructions below.

To request a certificate from your CA using the step CLI, bootstrap your CA with step ca bootstrap and run the following command (sub the server name for the actual name / DNS name of your Redis server).

step ca certificate "redis.example.net" server.crt server.key

Your certificate and private key will be saved in server.crt and server.key respectively.

Request a copy of your CA root certificate, which will be used to make sure each application can trust certificates presented by other applications.

step ca root ca.crt

Your certificate will be saved in ca.crt.

Configure Redis to use the certificate

You can test your certificate by starting up Redis with TLS enabled.

Native "SSL Support" (TLS) was added to Redis 6.0.0, which was released GA on April 30, 2020. TLS in Redis is an optional feature and not all Redis server binaries will have it enabled. The official Docker image, and many OS distribution images, have TLS enabled.

redis-server \
    --tls-port 6379 --port 0 \
    --tls-cert-file /path/to/server.crt \
    --tls-key-file /path/to/server.key \
    --tls-ca-cert-file /path/to/ca.crt \
    --tls-auth-clients no

6379 is the default port that redis-cli (and probably SDKs) connect to.

Setting --port 0 disables the non-TLS TCP socket.

--tls-auth-client no disables client authentication (which is on by default).

The server's private key can be password-protected using PEM encryption. Use step crypto change-pass to encrypt the private key. Then, the server will prompt for the password at startup, or you can provide it using --tls-key-file-pass <password>.

Test Redis TLS configuration

Send a PING command to Redis to test your TLS configuration:

$ redis-cli --tls --cacert /path/to/ca.crt ping
PONG

Operationalize It

Select a provisioner

Smallstep CAs use provisioners to authenticate certificate requests using passwords, one-time tokens, single sign-on, and a variety of other mechanisms.

ACME ( RFC8555) is an open standard, used by Let's Encrypt, for authenticating certificate requests. To use ACME on a private network you need to run an ACME server. ACME is harder to setup, but has a large client ecosystem (some software even has built-in support).

Other provisioners use the open source step CLI and do not require a local network agent. The instructions below focus on the JWK provisioner, but can be repurposed with small tweaks to operationalize all non-ACME provisioners.

To learn more, see Configuring step-ca Provisioners.

The JWK provisioner is the most general-purpose provisioner. It supports password and one-time token-based authentication. To add a JWK provisioner called redis to a hosted Certificate Manager authority (if you haven't already), run:

step ca provisioner add redis --type JWK --create --x509-default-dur 720h

Configure Redis TLS Certificate Automation

We've created a systemd-based certificate renewal timer that works with step. Check out our documentation on Renewal using systemd timers for background on how these timers work.

To install the certificate renewal unit files, run:

cd /etc/systemd/system
sudo curl -sL https://files.smallstep.com/cert-renewer@.service \
     -o cert-renewer@.service
sudo curl -sL https://files.smallstep.com/cert-renewer@.timer \
     -o cert-renewer@.timer

The renewal timer will check your certificate files every five minutes and renew them after two-thirds of their lifetime has elapsed.

To renew and hot-reload the Redis server certificate, we will need a Redis-specific systemd override file that can tell Redis to refresh its certificates. To install the override, run:

sudo mkdir /etc/systemd/system/cert-renewer@redis-server.service.d
cat <<EOF | sudo tee /etc/systemd/system/cert-renewer@redis-server.service.d/override.conf
[Service]
; "Environment=" overrides are applied per environment variable. This line does not
affect any other variables set in the service template.
Environment=CERT_LOCATION=/var/lib/redis/redis.crt \
            KEY_LOCATION=/var/lib/redis/redis.key \
            REDIS_USERNAME=default \
            REDISCLI_AUTH=""
; Empty ExecStartPost (Don't attempt to restart redis-server.service)
ExecStartPost=
ExecStartPost=redis-cli --user "$REDIS_USERNAME" --tls --cacert /var/lib/redis/ca.crt config set tls-cert-file $CERT_LOCATION
EOF

To start the renewal timer, run:

sudo systemctl daemon-reload
sudo systemctl enable --now cert-renewer@redis-server.timer

Distribute your root certificate to end users and systems

Once Redis TLS is configured, you'll need to make sure that clients know to trust certificates signed by your CA. For certificates signed by a public CA (like Let's Encrypt), most clients already include the CA root certificate in their trust stores for certificate verification. But, for a private CA, you will need to explicitly add your CA's root certificate to your clients' trust stores.

The step CLI includes a utility command for this purpose on many systems:

step certificate install ca.crt

Rather than manually running the above for each machine that needs to trust your CA, most teams will use some form of automation to distribute the root certificate. Depending on your needs and your IT or DevOps team's approach, this may be a configuration management tool (like Ansible or Puppet), a Mobile Device Management (MDM) solution, or something else.

Research notes

In researching Redis TLS, we did some thorough investigation. Here are our rough notes if you are interested in diving deeper.

General notes

Redis client & server (redis-cli and redis-server) do not use your system's trust store. They require explicitly configuration of trusted CA root(s) (i.e., trust store).

Client authentication can also be enabled for clustered / replicated deployments. Client certificates are then required for establishing cluster bus and replication connections. You can provide a different certificate for Redis servers to use as client certs for these connections, but you can't configure a different root CA (i.e., the same root CA is used to verify client certs for normal clients, replicas, and cluster nodes).

To verify that the requester of the certificate actually controls the DNS name specified in your ACME request, the ACME CA will send an HTTP challenge request to that DNS name and expects to receive particular response. For this reason, your Kubernetes cluster must have some HTTP ingress configured, and your DNS name must resolve to that ingress.