At Frederick we use Redis extensively. We currently have over 20 production Redis databases and at least as many for pre-production / testing.

In order to manage all of these Redis instances and make it easy to add new ones for new services, we use Redis Labs’ Redis Cloud offering. They provide us a hosted Redis cluster on AWS that supports a large number of Redis databases (constrained only by overall cluster size).

Security and Redis

Redis was built for speed and simplicity, but does not include any native security features beyond plain text password authentication. This is fine when Redis is run on the same host as your application, but otherwise, connections between services on different hosts should generally be securely encrypted, using a technology such as SSL / TLS.

Thankfully, open source solutions exist for layering SSL on top of Redis. The most popular solution is called Stunnel. Stunnel can be run on both the server and client to add SSL to any service by opening an external port that only accepts encrypted connections, then proxying to the local service. Both Redis Cloud and Heroku Redis on certain paid plans have implemented Stunnel (or a similar solution) on the server side, so we just need to connect with an appropriate certificate on the client side.

Enabling SSL in Redis Cloud

If you have a Redis Cloud plan that supports SSL, you must enable it per Redis database. When migrating an existing database to SSL, it will no longer accept unencrypted connections, so you may take some downtime when transitioning your Redis clients to SSL.

Redis Labs will generate a client certificate for you when you enable SSL. Download and unzip the certificate files – we’ll use them to set Heroku environment variables.

For Ruby / Rails Projects, Enable SSL with redis-rb

If you’re using Ruby, the popular redis-rb client now supports connecting via SSL. This support has been added in versions 3.3.0 and later and makes it no longer necessary to use Stunnel for Ruby / Rails apps using the latest versions of redis or redis-rails gems.

First, Add the certificates and private key to your Heroku ENV:

heroku config:set REDIS_URL=redis://{redis url from redis cloud}
heroku config:set REDIS_TRUSTED_CERT=$(cat redislabs_ca.pem)
heroku config:set REDIS_CLIENT_CERT=$(cat redislabs_user.crt)
heroku config:set REDIS_CLIENT_CERT_KEY=$(cat redislabs_user_private.key)

Next, configure redis-rb (example below for using redis-rails as your Rails cache store):

# in config/production.rb
redis_ssl_ca_store = OpenSSL::X509::Store.new
redis_ssl_ca_store.add_cert(OpenSSL::X509::Certificate.new(ENV['REDIS_TRUSTED_CERT']))
redis_ssl_params = {
  cert_store: redis_ssl_ca_store,
  cert: OpenSSL::X509::Certificate.new(ENV['REDIS_CLIENT_CERT']),
  key: OpenSSL::PKey::RSA.new(ENV['REDIS_CLIENT_CERT_KEY'])
}

config.cache_store = :redis_store, ENV['REDIS_URL'], {
  pool_size: Integer(ENV['MAX_PUMA_THREADS'] || 5),
  pool_timeout: 5,
  compress: true,
  ssl: true,
  ssl_params: redis_ssl_params
}

Or, Use Stunnel with Redis Cloud

Alternatively If your Redis client doesn’t support SSL natively, you can also run Stunnel on your Heroku dynos to proxy your Redis connection through an SSL tunnel. Heroku provides a buildpack for Heroku Redis, which we have forked to support Redis Cloud.

See: Redis Cloud Heroku Buildpack

To use this buildback, you’ll store your client certificate and key in Heroku environment variables, then when running your application, you’ll prefix your Procfile commands with bin/start-stunnel, which will transparently enable SSL for any Redis connection.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s