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 Redis TLS certificate renewal and enabling server-side encryption.
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:
step-caTo 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.keyYour 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.
You can test your certificate by starting up Redis with 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.--port 0 disables the non-TLS TCP socket.--tls-auth-client no disables client authentication (which is on by default).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>.Send a PING command to Redis to test your TLS configuration:
$ redis-cli --tls --cacert /path/to/ca.crt ping
PONGSmallstep CAs use provisioners to authenticate certificate requests using passwords, one-time tokens, single sign-on, and a variety of other mechanisms.
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 right provisioner depends on your operational environment.
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 720hFor instructions on adding provisioners to open source step-ca, or to learn more about other provisioner types, see Configuring step-ca Provisioners.
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
If you use password authentication in Redis,
you'll need to update the REDIS_USERNAME and/or REDISCLI_AUTH.
Otherwise, leave them alone.
To start the renewal timer, run:
sudo systemctl daemon-reload
sudo systemctl enable --now cert-renewer@redis-server.timerYou'll see that the timer is active, by checking the output of systemctl list-timers.
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. Some examples:
ca.crt directly to the ca-ceritficates bundle on linux VMs so running applications trust the API servers they callca.crt directly into base Docker images for gRPC so gRPC clients can always reference the trusted CAca.crt in a Kubernetes Secret and inject it into an environment variable for access from application codeca.crt in the trust stores of every employee Macbook so their web browsers trust internal websitesstep certificate install ca.crt on target machines that want curl to implicity trust the CAca.crt in a Kubernetes ConfigMap and mount it to pods for reference on the filesystemAlternatively, many clients support passing the CA root certificate as a flag or argument at runtime.
In researching Redis TLS, we did some thorough investigation. Here are our rough notes if you are interested in diving deeper.
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).node-redis & go-redis/redis) and they both used the language-default behavior.golang uses the system truststorenode ships their own trust store, but you can use the EXTRA_CA_CERTS env var to add moreredis-cli doesn't do name validation on the server certificate. The server's hostname does not need to match the certificate subject (CN/SANs).redis-cli client.node-redis & go-redis/redis) and they both implement proper certificate path validation and verify the server name.redis-cli is doing here, but I suppose it isn't too terrible if you trust everything that can get a certificate from your CA. However, I'd check client libraries carefully to make sure there aren't any that 1) trust the system trust store, and 2) disable server name verification. In that scenario, anyone with a Web PKI certificate would be able to MITM your Redis server.masterauth directive to specify a password / shared secret to authenticate replicas. This would allow you to authenticate replicas and would prevent normal clients from connecting to the replication API.CERT_FILE=$(redis-cli --tls --cacert .step/certs/root_ca.crt --raw config get tls-cert-file | tail -n1)
REDIS_USERNAME=default
REDISCLI_AUTH=""
redis-cli --user "$REDIS_USERNAME" --tls --cacert /path/to/root_ca.crt config set tls-cert-file ${CERT_FILE}
SIGHUP. But it does support dynamic configuration, and if you set the tls-cert-file directive it will reload the cert.
This is the recommended approach to force a certificate reload.
Note that the value here is the filesystem path to the server's certificate.
We're not actually changing it, we're literally reading the existing value and then writing that value again.--insecure option was added to redis-cli in version 6.2 which fixes this.tls-ca-cert-dir directive is complicated: https://github.com/redis/redis/issues/7392The Practical Zero Trust project is a collection of living documents detailing TLS configuration across a broad spread of technologies. We'd love to make this document better. Feel free to contribute any improvements directly on GitHub.
Unsubscribe anytime. See our privacy policy.
© 2023 Smallstep Labs, Inc. All rights reserved.