Securing Heroku Redis Versions 4 and 5
Last updated December 28, 2021
Table of Contents
This article only applies to Redis versions 4 and 5. If you provision your Premium, Private, or Shield Heroku database with Redis version 6, you must use its built-in TLS instead of the Stunnel technique described in this article. Heroku doesn’t support Redis versions older than 4.
Redis has native TLS support starting with version 6. If you’re using Redis 4 or 5, data transmits between dynos and Redis unencrypted unless you’re using a method from this article.
To improve the safety and privacy of your Heroku Redis data at the transport level, use the Stunnel buildpack. This buildpack creates an SSL tunnel between your dynos and your Heroku Redis instance, allowing for secure transmission of your data.
While you can connect to Heroku Redis 5 or older without the Stunnel buildpack, it isn’t recommended. Without it, the data travels over the wire unencrypted.
Stunnel Overview
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. You must create an associated Stunnel on the dynos that run your application to ensure security at the transport level. The Stunnel buildpack adds encryption to your application without any changes to the application code.
Using the Stunnel Buildpack
Stunnel is already set up on the server-side of all production-tier Heroku Redis instances. You must set up the other half of the tunnel on the dynos that interact with Heroku Redis.
At a high level, you must install the Stunnel buildpack and update your Procfile
. Update it so that each process type that interacts with Heroku Redis also runs bin/start-stunnel
.
The Heroku Redis Stunnel Buildpack README has all of the details of adding the buildpack to your application.
After installing the buildpack, enable or disable the Stunnel buildpack by setting the STUNNEL_ENABLED
config var to true
or false
.
Connecting Directly to Stunnel
Some Redis client libraries allow connections directly to the server-side Stunnel available on your Heroku Redis instance. In this case, you don’t need the Stunnel buildpack and can connect directly to the Stunnel.
The server-side Stunnel process runs one port higher than your Heroku Redis instance port. For example, if your Redis service runs on port 6379
, Stunnel listens to port 6380
.
Using Ruby
If you’re using Ruby, you can 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. You can’t use 4.0.1
or below to connect to Heroku Redis over SSL natively as they ignore OpenSSL::SSL::VERIFY_NONE
as a verification mode.
Using Go
If you’re using Go, you can 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 connects via Stunnel when trying to access your Heroku Redis instance for production plans.
For Hobby plans, which don’t have Stunnel support, the Heroku CLI raises a warning asking for confirmation to proceed with the unencrypted connection:
$ heroku redis:cli -a example-app
▸ WARNING: Insecure Action
▸ All data, including the redis password, will be unencrypted.
▸ To proceed, type example-app or re-run this command with --confirm example-app
>
At the command line, use the --confirm
flag to bypass the confirmation message and connect unencrypted to the Redis CLI:
$ heroku redis:cli --confirm example-app
Connecting to: REDIS_URL
ec2-11-11-11-11.compute-1.amazonaws.com:6699>