How to stunnel to Redis On-Demand with stunredis

If you have TLS/SSL secured Redis, you’ll want this

--

Introducing stunredis, a script to turn the trickiness of configuring a TLS/SSL tunnel for Redis into an automated breeze, and showing you how the magic is done.

When we introduced TLS/SSL connections to IBM Cloud Compose for Redis we knew we would have some explaining and teaching to do. The thing with Redis is there’s no out-of-the-box TLS/SSL support, but there is a community formula — using a TLS/SSL enabled proxy in front of the database server — to provide that functionality. That formula has led to many, if not most Redis drivers and libraries knowing about TLS or supporting the informal “rediss://” protocol. It all works really.

There’s just one problem: the redis-cli command. It has no idea how to talk TLS/SSL. The initial solution to that problem is, as we documented at the time, to install and configure the stunnel utility which wraps a connection in a TLS/SSL encryption tunnel and then send the redis-cli connection down that. And that works.

The only thing is if you have more than one Redis deployment to work with. Then for each one, you have to go edit /usr/local/etc/stunnel/stunnel.conf, file and add an entry for that server, and allocate a port for that server… and you may only need to just dive in for a minute to run a couple of commands. There had to be an easier way.

The easier way

We’ve put together a script called stunredis.sh which uses the stunnel utility but in such a way that there’s no configuration file. You’ll find the script and associated files to download in the ibm-watson-data-lab/stunredis Github repository. Download it and chmod u+x stunredis.sh to make the script executable.

Once you have done that, run ./stunredis.sh. All you need to pass to the script is the connection string for a deployment and the script does the rest. Here’s an example session with it:

Here you can see stunnel starting up and making the connection and letting the user interact through redis-cli. When the user exits the redis-cli session…

… the script closes down the stunnel session.

Before doing this, of course, you’ll need to install the stunnel and redis-cli commands. On macOS, we recommend the Homebrew package manager; once installed just run brew install redis stunnel and you’ll be good to run the script.

How it works

This all starts with a discovery. We can only assume that someone else somewhere had a similar need to create on-the-fly configurations for stunnel because one of the options on the command is -fd N which tells it to take its configuration data from a numbered file descriptor. We’ll use 0 to take that input from stdin.

What we put into stdin, by way of an echo -e command is a string we’ve composed to look like an appropriate configuration file. Here’s the code that builds that string:

For our example session above, the result would look like this:

The hostname and port — and combined host and port — have been parsed from the connection string. The same code also extracts the password from the connection string, but we don’t use that in the stunnel configuration.

That “6830” in the accept= line is the setting for the local port. The value is actually our default setting for a port. You can override it with your own local port by adding the port number as a separate parameter after the connection string when running the script. You will want to do that if you want to run two or more instances of this script at the same time.

About lechain.pem

Finally, there’s the CAfile= setting. This points to a file with the certificates needed to verify the connection. We use a file called lechain.pem which, for simplicity, is located in the same directory as the stunredis.sh script. You can move it wherever you want, as long as you change the variable, set earlier in the script, which contains the path to the certificates.

The lechain.pem file is a sample of the verification chain for Let’s Encrypt. It does work, but do not use for production if you are concerned about correctness; as with all things security related, get your own version from a trusted source or sources.

You can create your own version of lechain.pem by downloading and combining the contents of the Let’s Encrypt X3 Cross-signed PEM file and the IdenTrust Root for X3. The latter link’s content will need to be wrapped in the same -----BEGIN CERTIFICATE----- / -----END CERTIFICATE----- lines that the first link’s content is wrapped in. Consult lechain.pem for an example of how it should look.

Back to the script

So now we have a variable full of configuration, a password we haven’t used yet and a setting for a local port. It’s time to bring them all together. First, we run stunnel. The configuration will stop it running as a daemon, but we’ll run it in the background anyway, otherwise we’d stop here.

Now, we grab the process id of that stunnel process for later and, because it may still be setting up, we sleep for a second before carrying on.

We can now run the redis-cli command. We pass it the local port setting we embedded in the configuration and the password as derived from the connection string.

The user will now be in redis-cli and able to issue commands. When the user is done and they exit redis-cli, we just need to tidy up by killing off the stunnel process.

Wrapping up

You now have a way to stunnel to Redis on demand with stunredis.sh. This is the first released version, and we’re sure people will have their own enhancements or fixes for it. That’s why we’re more than happy to accept pull requests on it. This version is tested on macOS and Linux. Let us know if you need a Windows version by adding to the repository’s issues.

Resources

Originally published on Compose.com/articles on March 15, 2018.

--

--

Dj Walker-Morgan
Center for Open Source Data and AI Technologies

Geek who writes, code or words currently engaged @composeio to do just that. Also blogs at http://codescaling.com/ and curates @hackwimbledon.