Back to blog

Redis over SSL

April 14, 2014 - Posted in Web Posted by:

Tags: , ,

On a recent project the security team insisted all traffic between Redis and web server be encrypted. As you know Redis doesn’t support SSL so I looked around at a few solutions. A few people mentioned using an SSH tunnel, others stunnel and others still rolling your own SSL into Redis. Right away I dismissed rolling my own, besides being very difficult and with the recent heartbleed bug and bad patching from Akamai, if antirez won’t do it, I certainly am not. That leaves SSH tunnel or using stunnel.

SSH tunnel

This was my first choice, easy to implement and no code change. So I created a test env, then created a tunnel:

ssh -C -c arcfour -L 9999:localhost:6379 redisbox

So I have compression enabled, using the arcfour cypher (seems to be the fastest), made it listen on localhost:9999 talking to port 6379 on redisbox.
All good? No. It works perfectly but the performance hit is huge. See below.

stunnel

stunnel is described as an SSL encryption wrapper. It does exactly that, it sits on the client and the Redis server and encrypts the traffic between them.
Setting up stunnel is pretty straight forward.

  1. Download the source.
  2. Extract and build the source.
  3. I didn’t do a make install, just created the binary and used it.
  4. On the Redis server, create a new private key
    openssl genrsa -out key.pem 2048
    openssl req -new -x509 -key key.pem -out cert.pem -days 1095
    cat key.pem cert.pem >> redis.pem
    chmod 600 redis.pem
  5. Create an stunnel.conf (listening on port 63791 and connecting to Redis locally on the default port)
    [redis]
    accept = 63791
    connect = 127.0.0.1:6379
    cert = redis.pem
  6. Start stunnel on Redis server
    ./stunnel stunnel.conf
  7. Copy the redis.pem created earlier to the client machine.
  8. Build stunnel on the client (You can copy the one you created earlier if you are running similar OS’s and flavors).
  9. Create an stunnel.conf (accept connections locally on the redis default port and send them to the stunnel on the redis server )
    cert = redis.pem
    client = yes
    [redis]
    accept = 127.0.0.1:6379
    connect = redisbox:63791
  10. Start stunnel on client
    ./stunnel stunnel.conf

Thats is, you can now connect to Redis as you would if it lived on the local machine and all traffic is sent over SSL.

Performance

I done some very simple testing against the frontend web server, for each page request, the web server made 500 Redis gets. I used siege to do the http requests, PHP was the server side language making the Redis calls. As you can see, the SSH tunnel was a good deal slower than stunnel, while stunnel itself was pretty close to native.

Redis Performance Graph

As always, take these results with a pinch of salt, lots of other factors are to play and I know siege isn’t the best, but for me it showed a clear difference in performance.

One Comment

szegad 9 years ago

Hi,
Maybe you could try persistent ssh connections with ControlPersist ?
Initial handshake is a costly operation.

Leave a Reply

Your email address will not be published. Required fields are marked *