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.
- Download the source.
- Extract and build the source.
- I didn’t do a make install, just created the binary and used it.
- 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
- 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
- Start stunnel on Redis server
./stunnel stunnel.conf
- Copy the redis.pem created earlier to the client machine.
- Build stunnel on the client (You can copy the one you created earlier if you are running similar OS’s and flavors).
- 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
- 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.
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 10 years ago
Hi,
Maybe you could try persistent ssh connections with ControlPersist ?
Initial handshake is a costly operation.