Securing Heroku Redis
Last updated 12 August 2019
Table of Contents
Heroku Redis provides access to Redis, an in-memory, key-value store that has excellent support for all of the official languages on Heroku. It has a number of powerful data types and focuses on maximizing throughput. As a result, Redis is designed to run in trusted environments with trusted clients. This means that Redis lacks encryption, has minimal access controls, and the authentication layer consists only of a plain-text password with no challenge-response.
To make sure that the data that developers produce and work with is safe, we’re recommending everyone that wants to connect to Redis install a Heroku-provided Stunnel buildpack. This build pack will create an SSL tunnel between your dynos and your Heroku Redis instance.
While you can connect to Heroku Redis without the Stunnel buildpack, it is not recommend. The data traveling over the wire will be unencrypted.
Stunnel Overview
SSL for Heroku Redis is only available on production tier plans. The hobby-dev plan is meant for testing and staging environments, not production.
Stunnel is software that’s installed on each production Heroku Redis instance. It creates a proxy between the running Redis process and the SSL connection. An associated Stunnel needs to be created on the dynos that are running your application so that transport level security is taken care of. Generally, the benefit of using Stunnel is that it adds encryption to your application without any changes to the application code.
Using the Stunnel buildpack
Stunnel is already setup on the server-side of all production-tier Heroku Redis instances. The other half of the tunnel needs to be set up on the dynos that need to interact with Heroku Redis. At a high level, a buildpack needs to be installed and each process type that interacts with Heroku Redis needs to have its command prefaced with bin/start-stunnel
. The Heroku Redis Buildpack README has all of the details of adding the buildpack to your application.
You can disable the stunnel buildpack on your staging or development environment by setting STUNNEL_ENABLED
to false
using heroku config:set STUNNEL_ENABLED=false -a sushi
Connecting directly to stunnel
Some Redis client libraries allow connections directly to the Stunnel . If this is the case, you do not need to use the Stunnel buildpack and can connect directly to the Stunnel.
We run Stunnel on the next higher port to your Redis instance port: if your Redis run on port 6379
, Stunnel will be listening to port 6380
.
Using Ruby
If you’re using Ruby, you will be able to connect directly to Stunnel using:
require 'uri'
url = URI.parse(ENV["REDIS_URL"])
url.scheme = "rediss"
url.port = Integer(url.port) + 1
$redis = Redis.new(url: url, driver: :ruby, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
This method only applies to versions of the redis
gem 4.0.2
and up. 4.0.1
and below ignore OpenSSL::SSL::VERIFY_NONE
as a verification mode, and so cannot be used to connect to Heroku Redis over SSL natively.
Using Go
If you’re using Go, you will be able to connect to Stunnel using:
u, _ := url.Parse(s)
h, p, _ := net.SplitHostPort(u.Host)
port, _ := strconv.Atoi(p)
u.Scheme = "rediss"
u.Host = net.JoinHostPort(h, strconv.Itoa(port++))
c, _ := redis.DialURL(u.String(), redis.DialTLSSkipVerify(true))
defer c.Close()
Using Node.js
If you’re using ioredis to connect to your Heroku Redis instance from Node.js, you can connect directly to Stunnel using:
var url = require('url');
var Redis = require('ioredis');
redis_uri = url.parse(process.env.REDIS_URL);
var redis = new Redis({
port: Number(redis_uri.port) + 1,
host: redis_uri.hostname,
password: redis_uri.auth.split(':')[1],
db: 0,
tls: {
rejectUnauthorized: false,
requestCert: true,
agent: false
}
});
Heroku Redis CLI
The Heroku Redis CLI will connect via stunnel when trying to access your Heroku Redis instance. Because the hobby-dev plan does not have any stunnel support, when you connect to your Heroku Redis instance via the CLI, a warning message will be given asking for confirmation:
$ heroku redis:cli -a sushi
▸ WARNING: Insecure Action
▸ All data, including the redis password, will be unencrypted.
▸ To proceed, type sushi or re-run this command with --confirm sushi
>
At the command line, the --confirm
flag can be used to bypass the confirmation message and connect directly to the Redis CLI:
$ heroku redis:cli --confirm sushi
Connecting to: REDIS_URL
ec2-11-11-11-11.compute-1.amazonaws.com:6699>