How to Connect to Managed Redis over TLS with stunnel and redis-cli
A managed Redis instance can offer advantages such as high availability, automatic updates, and provider-managed maintenance. However, whenever a remote database is accessed across a network, unencrypted communication may be vulnerable to packet sniffing and other forms of interception. Transport Layer Security (TLS) protects this traffic by encrypting credentials, keys, commands, and other data instead of transmitting them as plaintext.
Starting with Redis 6, redis-cli can establish a direct TLS connection with the --tls option when the installed client was compiled with TLS support. On current systems, this native functionality is generally the simplest method. If an older client or an application without TLS support must be used, a local TCP connection can instead be secured with stunnel, an open-source TLS proxy that handles encryption between the local client and the remote service.
This guide explains how to install redis-cli and stunnel on Ubuntu 24.04 LTS, connect securely to a managed Redis instance with native TLS, configure stunnel as an alternative connection method, understand CA certificate verification, compare secure connection approaches, and troubleshoot common TLS, authentication, DNS, and connectivity problems.
Prerequisites for Connecting to Managed Redis over TLS
To follow this guide, you will need:
- Access to an Ubuntu 24.04 server with a non-root account that has
sudoprivileges and a firewall configured withufw. If the system has not yet been prepared, complete an initial Ubuntu server setup first. - A managed Redis database instance that requires TLS. The connection methods described here apply to cloud and hosting providers that expose a TLS-enabled Redis endpoint.
Before running any commands, collect the Redis hostname, TLS port, and password from the database provider’s management interface or API. Preparing these connection values in advance makes the configuration process easier and avoids searching for credentials during setup.
Choosing a Secure Redis Connection Method
Managed Redis services commonly provide a dedicated TLS listener and may reject plaintext connections. Several methods can be used to access such an endpoint securely from an Ubuntu client.
| Method | How it works | Best for |
|---|---|---|
Native redis-cli TLS |
redis-cli communicates directly with the remote server over TLS by using --tls and, when necessary, certificate-related options. |
Modern Redis clients running Redis 6 or newer, regular administration, and scripts. |
| stunnel client tunnel | stunnel listens locally on 127.0.0.1:8000, encrypts the connection, and forwards it to the remote Redis TLS port. redis-cli connects to 127.0.0.1 without TLS options. |
Older redis-cli versions, applications that support only plaintext TCP, or systems where the client cannot be upgraded or rebuilt. |
| SSH local port forwarding | ssh -L forwards a local port through an SSH connection to the Redis host or an intermediate bastion server. Redis traffic travels inside the encrypted SSH tunnel. |
Environments that already use SSH bastions and need encryption without installing stunnel on every client system. |
Native TLS is generally the preferred option. It involves fewer components, does not require an additional daemon, and allows redis-cli to verify the server certificate directly, following the recommendations in the Redis TLS documentation and redis-cli documentation.
Stunnel remains useful when the installed redis-cli binary does not include TLS support, which can be identified when redis-cli --help does not show the --tls option. It is also suitable when another local program expects a standard plaintext TCP socket. The following sections cover both native TLS and stunnel.
SSH port forwarding does not provide Redis-specific TLS itself. Instead, it encrypts communication between the client machine and the SSH server. This can be an effective operational approach when the Redis network can only be reached through a jump host, but detailed SSH tunnel configuration is outside the step-by-step process covered here.
Understanding CA Certificate Verification for Redis TLS
TLS provides more than encryption. It also allows the client to verify that it has reached the correct remote server rather than an unauthorized system intercepting the connection.
When redis-cli connects with --tls, OpenSSL or the operating system’s TLS library performs a handshake. During this process, the server presents an X.509 certificate and the client verifies several properties:
- The certificate must chain back to a trusted root Certificate Authority (CA).
- The certificate must still be valid and not expired. If specifically configured, revocation status can also be checked.
- The certificate identity must correspond to the hostname used for the connection.
The trusted CA configuration can be controlled with the following options:
--cacert: specifies a PEM file containing one or more trusted CA certificates or a CA bundle supplied by the service provider.--cacertdir: specifies a directory containing hashed CA certificates, similar to the layout used by the operating system certificate store.
If the managed Redis service uses a certificate issued by a public CA already trusted by the operating system, such as Let’s Encrypt, a custom --cacert file may not be necessary. On an up-to-date Ubuntu installation, using --tls alone can therefore be sufficient when the provider relies on a publicly trusted certificate authority.
If certificate verification fails, redis-cli reports a certificate-related error instead of completing the connection. Redis also provides the --insecure option for debugging, which disables certificate validation. This option should not be used for production connections because bypassing validation makes man-in-the-middle attacks possible. It is intended only for controlled testing and troubleshooting environments, as discussed in the Redis command-line tools implementation discussion.
Some managed Redis environments use mutual TLS, or mTLS, and require the client to provide its own certificate. In this situation, --cert and --key are supplied together with --cacert, following the manual TLS connection examples in the Redis documentation.
When stunnel is used instead of native TLS, stunnel is responsible for validating the certificate presented by the remote server. Chain verification can be enabled in stunnel.conf with verifyChain = yes and CApath = /etc/ssl/certs, following the official stunnel Unix configuration examples.
Step 1: Install stunnel and redis-cli on Ubuntu 24.04
A Redis server installation normally includes redis-cli. On Ubuntu 24.04, it is also possible to install only the Redis client tools together with stunnel from the standard repositories. This avoids installing a local Redis server when the system only needs administrative access to a remote database.
First, refresh the local APT package index so the system can retrieve current package information:
sudo apt update
Next, install redis-tools, which contains redis-cli, together with stunnel4:
sudo apt install redis-tools stunnel4
Press ENTER when APT requests confirmation.
After the packages have been installed, verify the installed versions:
redis-cli –version
stunnel4 -version
Ubuntu 24.04 provides a Redis 7.x version of redis-tools, which includes native TLS functionality. The output should therefore show a 7.x release for redis-cli and a 5.x release for stunnel.
Before selecting a connection method, confirm that the installed redis-cli binary includes TLS support:
redis-cli –help 2>&1 | grep -E ‘–tls|–cacert’
If the output contains --tls and --cacert, the native TLS procedure in Step 2 can be used. If these options are unavailable, use the stunnel process described in Steps 3 and 4.
Finally, verify that the stunnel systemd service exists:
sudo systemctl status stunnel4
Immediately after installation, the service may display active (exited) together with a message such as TLS tunnels disabled, see /etc/default/stunnel4. This is expected because the software is installed but no tunnel has been enabled and configured yet.
Step 2: Connect to Managed Redis with Native redis-cli TLS
This method allows redis-cli to connect directly to the TLS endpoint of the managed Redis service. Replace each placeholder with the hostname, port, and password supplied by the Redis provider.
Connect Using the System Certificate Trust Store
Use this method when the managed Redis server presents a certificate issued by a public CA that Ubuntu already trusts.
Run redis-cli with --tls, the Redis hostname, and the TLS port:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls
If authentication is required, first store the password in the REDISCLI_AUTH environment variable. This prevents the credential from appearing directly in shell history and is preferable on systems used by multiple accounts:
export REDISCLI_AUTH=your_redis_password
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls
The password can alternatively be passed directly with -a, although this is less desirable when other users are able to inspect command arguments or running processes:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls -a your_redis_password
Note: Use the connection information provided by the managed Redis service. The supplied connection parameters generally contain the correct hostname, TLS port, TLS setting, and authentication information for the database.
To test the connection without opening an interactive Redis session, send a single PING command:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls ping
A successful connection returns:
PONG
If PONG is returned, the TLS handshake completed successfully and the Redis server accepted the connection. Interactive commands can now be used. The stunnel configuration described later is only necessary when a local plaintext endpoint is also required.
Connect Using a Provider CA Certificate File
Some managed services use certificates issued by a private CA. If that CA is not already trusted by Ubuntu, obtain the provider’s CA bundle, such as a ca.pem file, and specify it explicitly:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port
–tls –cacert /path/to/ca.pem
Limit access to the PEM file so that only the current user can read it:
chmod 600 /path/to/ca.pem
Connect to Redis with Mutual TLS
If the remote server requires a client certificate, include the client certificate and private key together with the CA certificate:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port
–tls
–cacert /path/to/ca.pem
–cert /path/to/client.crt
–key /path/to/client.key
Connect with a Redis TLS URI
redis-cli also supports connection URIs. When TLS is required, use the rediss:// scheme described in the Redis CLI documentation:
redis-cli -u rediss://default:your_redis_password@managed_redis_hostname:managed_redis_tls_port
If native TLS functions correctly in the environment, redis-cli can be used for routine administration without stunnel. The following configuration is intended for situations where a local plaintext TCP port is still needed.
Step 3: Configure stunnel for Managed Redis TLS
redis-cli connects through plaintext TCP to 127.0.0.1:8000, while stunnel establishes the encrypted TLS connection to the remote Redis endpoint. On Debian and Ubuntu systems, stunnel integrates with systemd and uses /etc/default/stunnel4 to control service activation.
Enable stunnel Automatic Startup
Open the default configuration file with an editor:
sudo nano /etc/default/stunnel4
Set ENABLED to 1 so the stunnel service can start during boot and when it is restarted manually.
/etc/default/stunnel4
# Change to one to enable stunnel automatic startup
ENABLED=1
Save the file and close the editor.
Create the stunnel Redis Tunnel Configuration
Create or open the main stunnel configuration file:
sudo nano /etc/stunnel/stunnel.conf
Add the following configuration and replace the placeholders with values appropriate for the Redis environment:
/etc/stunnel/stunnel.conf
fips = no
setuid = nobody
setgid = nogroup
pid = /tmp/stunnel-redis.pid
debug = 5
delay = yes
[redis-cli]
client = yes
accept = 127.0.0.1:8000
connect = managed_redis_hostname_or_ip:managed_redis_tls_port
verifyChain = yes
CApath = /etc/ssl/certs
The global settings apply to every service defined in the file:
fips: When configured asyes, stunnel enforces FIPS 140-3 mode. Usingnoretains the normal cipher configuration without additional FIPS requirements.setuid/setgid: After starting, stunnel drops its privileges and runs asnobodyandnogroup, following the recommended stunnel configuration pattern.pid: Stores the process ID in/tmp/stunnel-redis.pid. This path remains writable after privileges are dropped and avoids permission problems that can occur with/var/run/stunnel4/when the process runs asnobody.debug: Controls logging detail from0, which is quiet, through7, which is highly verbose. Level5is normally sufficient and can temporarily be increased when investigating TLS handshake problems.delay: Postpones DNS resolution for theconnecttarget and prevents an address from being permanently cached. This can help the tunnel recover when a managed endpoint receives a different address during maintenance or failover.
The options below [redis-cli] control the Redis tunnel itself:
client = yes: Configures stunnel to operate as a TLS client when communicating with the remote server.accept: Defines the local address and port on which stunnel listens. Using127.0.0.1:8000limits access to processes running on the local server, which is appropriate for administrative connections.connect: Defines the hostname and TLS port of the remote managed Redis server.verifyChain/CApath: Validates the remote certificate against trusted CA certificates stored in/etc/ssl/certs, following the pattern used in the official stunnel client examples.
Note: The connect setting must use the TLS-enabled Redis port supplied by the managed service. Pointing stunnel at a plaintext port can cause the connection to fail immediately or produce an error such as Error: Server closed the connection.
Save the configuration and restart stunnel so that it loads the new settings:
sudo systemctl restart stunnel4
Confirm that the tunnel is listening on local port 8000:
sudo ss -tlnp | grep 8000
The output should be similar to:
LISTEN 0 128 127.0.0.1:8000 0.0.0.0:* users:((“stunnel4”,pid=12345,fd=7))
You can also verify that stunnel dropped its privileges successfully after startup:
ps aux | grep ‘[s]tunnel’
The stunnel4 process should be owned by nobody.
If the service does not start, review its latest log messages for syntax problems or TLS handshake errors:
sudo journalctl -u stunnel4 -n 50 –no-pager
Step 4: Connect to Redis Through the stunnel Tunnel
After stunnel begins listening on 127.0.0.1:8000, redis-cli connects to the local forwarding port through plaintext TCP. Stunnel then encrypts the traffic and sends it to the remote Redis TLS endpoint. The result is a two-stage connection: plaintext communication stays on the local loopback interface, while TLS protects traffic traveling across the network.
Connect to the local listener:
redis-cli -h 127.0.0.1 -p 8000
The hostname localhost can also be used:
redis-cli -h localhost -p 8000
Do not include --tls when connecting to this local port. TLS is handled by stunnel, so adding --tls would cause redis-cli to attempt another TLS negotiation against the local plaintext listener.
If Redis requires authentication, export the password before opening the connection:
export REDISCLI_AUTH=your_redis_password
redis-cli -h 127.0.0.1 -p 8000
The prompt should reflect the local connection endpoint:
1.
After the connection has been established, test the tunnel with PING:
127.0.0.1:8000> ping
Output:
PONG
A PONG response confirms that stunnel successfully forwarded the Redis command and received a response from the remote server. If stunnel cannot communicate with the remote endpoint or the TLS handshake fails, redis-cli may report:
Could not connect to Redis at 127.0.0.1:8000: Connection refused
Another possible result after a brief connection is:
Error: Server closed the connection
The troubleshooting section below explains how to investigate these problems systematically.
When the session is finished, leave interactive mode with:
127.0.0.1:8000> exit
If the stunnel configuration is modified later, reload the service so it reads the updated configuration:
sudo systemctl reload stunnel4
The tunnel can also be stopped and started manually when required:
sudo systemctl stop stunnel4
sudo systemctl start stunnel4
Troubleshooting Common Redis TLS and stunnel Errors
Connection and authentication problems may still occur after completing the configuration. Typical causes include mismatched settings, insufficient permissions, incorrect host information, or invalid connection parameters. The following sections cover common errors, their likely causes, and practical ways to resolve them.
Error: Server Closed the Connection
This message can appear when redis-cli successfully connects to the local stunnel listener but stunnel is unable to establish or maintain the secure connection to the remote Redis server. The output normally resembles:
Error: Server closed the connection
A common cause is an incorrect hostname or port in /etc/stunnel/stunnel.conf. Open the file and verify that the connect setting exactly matches the Redis server hostname and TLS port supplied by the hosting or database provider:
connect = your_redis_host:your_redis_port
Also verify that the port configured in the accept directive is the same port used by redis-cli. If the local tunnel listens on port 8000, connect with:
redis-cli -h 127.0.0.1 -p 8000
If the managed Redis service was recently restarted, resized, migrated, or otherwise changed, existing connections can also be reset. Reconnecting and authenticating again will often restore access.
Connection Refused When Running redis-cli
If redis-cli produces a message such as:
Could not connect to Redis at 127.0.0.1:8000: Connection refused
the stunnel service is usually stopped or is not listening on the expected address and port.
Start by checking the stunnel4 service state:
sudo systemctl status stunnel4
If it has stopped or failed, restart it:
sudo systemctl restart stunnel4
Confirm that stunnel is actually listening on a TCP port:
sudo ss -tlnp | grep stunnel
If no listening socket appears, the service probably failed during startup. Check the configuration for mistakes and inspect recent logs to determine the cause:
sudo journalctl -u stunnel4 -n 50 –no-pager
Review the messages for configuration errors, DNS problems, or permission failures.
Authentication Required or NOAUTH Authentication Required
Many managed Redis databases require authentication before commands can be executed. If a command is issued without successful authentication, Redis may return:
(error) NOAUTH Authentication required.
The password can be supplied during connection with -a:
redis-cli -h 127.0.0.1 -p 8000 -a your_password
Authentication can also be performed manually after entering the Redis CLI:
127.0.0.1:8000> auth your_password
Compare the password carefully with the value supplied by the managed database provider. Even a small formatting difference or an unintended trailing space can cause authentication to fail.
stunnel4 Starts but Immediately Exits
After installation or configuration changes, systemctl status stunnel4 may show active (exited). If the service continues exiting immediately after a tunnel configuration has been created, the service may not have been enabled correctly.
Open /etc/default/stunnel4 and confirm the following value:
ENABLED=1
If ENABLED is set to 0, stunnel will not remain active. Change the value and restart the service:
sudo systemctl restart stunnel4
Verify that the service is running with sudo systemctl status stunnel4 or confirm that it owns a listening socket with sudo ss -tlnp | grep stunnel.
Permission Errors Related to the stunnel PID File
After stunnel switches to the nobody account, it must still be able to write its PID file. If the PID location is under /var/run and cannot be accessed by nobody, the service may fail during startup.
The configuration in this guide places the PID file in /tmp:
pid = /tmp/stunnel-redis.pid
If the pid location has been changed, make sure its directory exists and can be written by the nobody account:
sudo touch /tmp/stunnel-redis.pid
sudo chown nobody:nogroup /tmp/stunnel-redis.pid
Adjust stunnel.conf if necessary and restart the service:
sudo systemctl restart stunnel4
If the directory is incorrect or the service account does not have sufficient permissions, correct the filesystem configuration before attempting another restart.
DNS Resolution Failures
If stunnel cannot resolve the managed Redis hostname, outbound connections cannot be established. This can occur after DNS changes at the service provider or because of a local network or DNS configuration problem. The logs commonly contain lookup failures or timeout messages.
Test hostname resolution from the server with:
nslookup your_redis_host
or:
ping your_redis_host
If the hostname cannot be resolved, verify that the configured host and port are still current and confirm that outbound networking and DNS resolution are functioning on the server.
To reduce problems caused by stale DNS information, especially when the managed service can change endpoint addresses, add the following setting to stunnel.conf:
delay = yes
The delay option instructs stunnel to perform DNS resolution whenever a new connection is created, reducing the chance of using an outdated address after infrastructure changes.
Managed Redis TLS and stunnel FAQs
How Do I Connect to Redis with TLS Using stunnel?
Install stunnel and redis-tools, then create a client tunnel in /etc/stunnel/stunnel.conf. Configure client = yes, set connect to the managed Redis hostname and TLS port, and create a local listener with accept, such as 127.0.0.1:8000. For certificate validation, use verifyChain = yes together with CApath = /etc/ssl/certs. If the operating system certificate store is not being used, provide an appropriate CA bundle through CAfile.
After enabling stunnel through /etc/default/stunnel4 and restarting it, connect through the local port without --tls:
export REDISCLI_AUTH=your_redis_password
redis-cli -h 127.0.0.1 -p 8000
In this configuration, redis-cli uses plaintext TCP only on the local loopback connection to stunnel. Stunnel encrypts the data before forwarding it to the remote TLS endpoint. The complete connection process is described in Step 4.
How Do I Connect Directly to Redis with redis-cli?
Many managed Redis services require encrypted connections. Redis 6 and newer versions of redis-cli support native TLS through --tls:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls
If the service uses a private Certificate Authority, explicitly provide its CA bundle:
redis-cli -h managed_redis_hostname -p managed_redis_tls_port
–tls –cacert /path/to/ca.pem
The password can also be stored in an environment variable before connecting:
export REDISCLI_AUTH=your_redis_password
redis-cli -h managed_redis_hostname -p managed_redis_tls_port –tls
Before using native TLS parameters, check whether the installed redis-cli binary includes TLS support:
redis-cli –help 2>&1 | grep -E ‘–tls|–cacert’
If --tls does not appear, the installed client was compiled without TLS support. Use the stunnel method described earlier instead.
Some self-managed Redis systems may still provide a plaintext connection endpoint. In such an environment, a direct non-TLS connection can be made with:
redis-cli -h managed_redis_hostname -p managed_redis_port -a your_redis_password
Plaintext connections should only be used when the specific provider or infrastructure explicitly supports them.
Why Does redis-cli Return Could Not Connect to Redis at 127.0.0.1:6379: Connection Refused?
This message indicates that no process is listening at the hostname and port selected by redis-cli. Because Redis uses port 6379 by default, this error commonly occurs when the -p argument is omitted while stunnel is listening on another local port, such as 8000.
When stunnel is being used, a refused connection normally means that stunnel is stopped, did not start correctly, or is listening on an address or port different from the one passed to redis-cli. Begin by checking the service:
sudo systemctl status stunnel4
Then confirm that a stunnel process is running and identify its listening port:
ps aux | grep ‘[s]tunnel’
sudo ss -tlnp | grep stunnel
The accept value in /etc/stunnel/stunnel.conf must correspond to the port used in the redis-cli command. If the service is unavailable or incorrectly configured, inspect the most recent logs:
sudo journalctl -u stunnel4 -n 50 –no-pager
The troubleshooting sections above provide additional steps for tunnels that reject connections or close them immediately.
What Does the CAfile Directive Do in stunnel.conf?
The CAfile directive tells stunnel where to locate a PEM file containing one or more trusted Certificate Authority certificates. Stunnel uses this certificate bundle when validating the TLS certificate presented by the managed Redis server.
The example configuration in this guide uses CApath = /etc/ssl/certs instead, which loads hashed certificates from the operating system trust store and follows the same approach shown in the official stunnel Unix examples. CAfile is useful when the Redis service supplies a private CA bundle that is not included in /etc/ssl/certs.
Whichever CA configuration is selected, use it together with certificate-chain verification:
verifyChain = yes
With verification active, stunnel checks whether the server certificate chains back to a trusted root CA, helping protect the outbound TLS connection from man-in-the-middle attacks.
Can I Use stunnel to Connect to Managed Redis on Windows?
Yes. stunnel provides a Windows installer and supports the same main configuration options available on Linux, including client, accept, connect, verifyChain, CAfile, and pid.
Install stunnel from its official source, create a stunnel.conf containing the managed Redis hostname and TLS port, and use Windows-compatible paths for CAfile and pid. After the stunnel service is started, configure redis-cli to connect to the local accept port. This follows the same two-stage connection design described in Step 4, and --tls is not passed to the local Redis client.
What Is the Difference Between stunnel Client Mode and Server Mode?
In client mode, configured with client = yes, stunnel accepts plaintext connections locally and creates an encrypted TLS connection to a remote server. This is the appropriate mode when redis-cli or another local application expects a normal TCP socket while the remote managed Redis endpoint requires TLS.
Server mode performs the reverse operation. Stunnel receives incoming TLS traffic from remote clients, decrypts it, and forwards the plaintext traffic to a local service. Because managed Redis services normally already expose a TLS endpoint, the local system connects as a TLS client with either redis-cli --tls or stunnel running in client mode instead of placing stunnel in server mode in front of Redis.
Is stunnel Still Necessary with Redis 6 or Newer?
For most modern installations, it is not necessary. Redis 6 introduced native TLS functionality, and current redis-cli packages on Ubuntu 24.04 can generally connect directly with --tls. This reduces the number of components involved and is the preferred approach described earlier in this guide.
Stunnel is still useful when redis-cli was compiled without TLS support, when older software only understands plaintext TCP, or when an application’s connection configuration cannot be changed. For normal administration with a modern client, native TLS is preferable, while stunnel can be retained as a compatibility layer for these situations.
How Do I Start stunnel Automatically at System Boot?
On Ubuntu and Debian, first set ENABLED=1 in /etc/default/stunnel4 and place the tunnel configuration in /etc/stunnel/stunnel.conf. Then enable the packaged systemd service:
sudo systemctl enable stunnel4
Verify that systemd considers the service enabled:
systemctl is-enabled stunnel4
After restarting the system, verify that the tunnel is still running and listening on the configured port:
sudo systemctl status stunnel4
sudo ss -tlnp | grep 8000
On CentOS, RHEL, and related Linux distributions, the service may be named stunnel instead of stunnel4. On these systems, use sudo systemctl enable stunnel. The configuration is still normally stored below /etc/stunnel/.
Conclusion
redis-cli, available with Redis 6 and newer, is generally the preferred method because it requires fewer components and gives the client direct control over certificate validation through options such as --cacert. Stunnel remains a practical alternative when a local plaintext port is required or when software without native TLS support must connect to Redis.Understanding CA certificate validation is important for keeping either method secure. Trust the correct certificate authorities, protect PEM files stored on disk, and limit the --insecure option to non-production testing.When a connection fails, treat a refused connection primarily as a listener or routing problem. Confirm that the expected process is running, verify that the configured ports and TLS settings correspond to those of the managed Redis service, and ensure that applicable network or firewall rules allow the client to connect.


