Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable TLS for Redis 6 on Sidekiq?

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:

  • https://bibwild.wordpress.com/2020/11/24/are-you-talking-to-heroku-redis-in-cleartext-or-ssl/
  • https://mislav.net/2013/07/ruby-openssl/
like image 870
ogirginc Avatar asked Jan 21 '21 19:01

ogirginc


People also ask

How do I enable TLS on the default Redis port?

To enable only TLS on the default Redis port, use: By default, Redis uses mutual TLS and requires clients to authenticate with a valid certificate (authenticated against trusted root CAs specified by ca-cert-file or ca-cert-dir ). You may use tls-auth-clients no to disable client authentication.

How do I integrate Sidekiq with Redis and Redis?

You will also need to add the sidekiq gem to the project to work with Sidekiq and Redis. Open the project’s Gemfile for editing, using nano or your favorite editor: Add the gem anywhere in the main project dependencies (above development dependencies): . . .

What is Sidekiq in rails?

Sidekiq is one of the more widely used background job frameworks that you can implement in a Rails application. It is backed by Redis, an in-memory key-value store known for its flexibility and performance. Sidekiq uses Redis as a job management store to process thousands of jobs per second.

How do I install Sidekiq on Linux?

Install Sidekiq by adding the gem to your Gemfile. Sidekiq has only one dependency, and that’s Redis. If you are using a Mac, you can install Redis using Homebrew: Create a new job in app/jobs to process jobs asynchronously: You can invoke this job as MyJob.perform_async (args). Start the Sidekiq process with bundle exec sidekiq.


Video Answer


2 Answers

Solution

Use OpenSSL::SSL::VERIFY_NONE for your Redis client.

Sidekiq

# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } }
end

Sidekiq.configure_client do |config|
  config.redis = { ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } }
end

Redis

Redis.new(url: 'url', driver: :ruby, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })

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

  • https://ogirginc.github.io/en/heroku-redis-ssl-error
  • https://devcenter.heroku.com/articles/securing-heroku-redis#connecting-directly-to-stunnel
like image 116
ogirginc Avatar answered Sep 20 '22 01:09

ogirginc


If you use ActionCable, you may also need to add verify_mode to the `cable.yml config:

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: my_app_production
  ssl_params:
    verify_mode: <%= OpenSSL::SSL::VERIFY_NONE %>

Source: https://github.com/chatwoot/chatwoot/issues/2420

like image 30
Ryenski Avatar answered Sep 20 '22 01:09

Ryenski