Problem
On my Ruby on Rails app, I keep getting the error below for the Heroku Redis Premium 0 add-on:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain)
Heroku Redis documentation mentions that I need to enable TLS in my Redis client’s configuration in order to connect to a Redis 6 database. To achive this, I have read SSL/TLS Support documentation on redis-rb. My understanding from it is; I need to assign ca_file
, cert
and key
for Redis.new#ssl_params
. The question is how to set these for Redis or through Sidekiq on Heroku?
Updates
Update 3: Heroku support provided an answer which solved the problem.
Update 2: Created Heroku support ticket and waiting response.
Update 1: Asked on Sidekiq’s Github issues and was adviced go write Heroku support. Will update this question, when I do get an answer.
Related Info
I have verified the app does work when the add-on is either one of the below:
- hobby-dev for Redis 6
- premium 0 for Redis 5
Versions:
- Ruby – 3.0.0p0
- Ruby on Rails – 6.1.1
- Redis – 6.0
- redis-rb – 4.2.5
- Sidekiq – 6.2.1
- Heroku Stack – 20
Some links that helped me to narrow down the issue:
3
Answers
Solution
Use
OpenSSL::SSL::VERIFY_NONE
for your Redis client.Sidekiq
Redis
Reason
Redis 6 requires TLS to connect. However, Heroku support explained that they manage requests from the router level to the application level involving Self Signed Certs. Turns out, Heroku terminates SSL at the router level and requests are forwarded from there to the application via HTTP while everything is behind Heroku's Firewall and security measures.
Sources
If you use ActionCable, you may also need to add
verify_mode
to the `cable.yml config:Source: https://github.com/chatwoot/chatwoot/issues/2420
If you are using Rails 5 you won’t be able to configure Redis’s
ssl_params
for ActionCable via thecable.yml
file. Instead you can manually set theredis_connector
attribute in an initializer, like this:And for more context on the implications of using
OpenSSL::SSL::VERIFY_NONE
and why it’s probably OK if you’re on Heroku:Using
OpenSSL::SSL::VERIFY_NONE
tells the client it’s OK to work with a self-signed certificate, no attempt will be made to verify that the cert was signed by a known Certificate Authority.The risk there is the possibility of a man-in-the-middle attack. If the client attempting to talk to Heroku Redis is not verifying that the SSL certificates it encounters are known to belong to Heroku (AKA, that those certificates are signed by a certificate authority that has verified that the entity that requested the cert is in fact Heroku), then an attacker who sits betweeen your client and Heroku Redis could create their own self-signed SSL certificate and pretend to be Heroku. This means they could potentially intercept any traffic you attempt to send to Heroku Redis.
In practice that is probably not a realistic scenario for a Heroku dyno talking to Heroku Redis.
Here’s a quote from Heroku support:
And here are some snippets from the AWS docs that seem to corroborate this:
https://aws.amazon.com/vpc/faqs/
And https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html