如何在 Sidekiq 上为 Redis 6 启用 TLS?

Posted

技术标签:

【中文标题】如何在 Sidekiq 上为 Redis 6 启用 TLS?【英文标题】:How to enable TLS for Redis 6 on Sidekiq? 【发布时间】:2021-04-26 07:05:40 【问题描述】:

问题

在我的 Ruby on Rails 应用程序中,Heroku Redis Premium 0 插件不断出现以下错误:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: 证书验证失败(证书链中的自签名证书)

Heroku Redis documentation 提到我需要在 Redis 客户端的配置中启用 TLS 才能连接到 Redis 6 数据库。为了实现这一点,我阅读了redis-rb 上的 SSL/TLS 支持文档。我的理解是;我需要为Redis.new#ssl_params 分配ca_filecertkey问题是如何为 Redis 或 Heroku 上的 Sidekiq 设置这些?

更新

更新 3:Heroku 支持提供了解决问题的答案。

更新 2:创建 Heroku 支持票并等待响应。

更新 1:Asked 关于 Sidekiq 的 Github 问题,并被建议去编写 Heroku 支持。当我得到答案时会更新这个问题。


相关信息

我已验证该应用程序在插件为以下任一情况时可以正常工作:

Redis 6 的爱好开发 Redis 5 的高级版 0

版本:

红宝石 – 3.0.0p0 Ruby on Rails – 6.1.1 Redis – 6.0 redis-rb – 4.2.5 Sidekiq – 6.2.1 Heroku 堆栈 - 20

一些帮助我缩小问题范围的链接:

https://bibwild.wordpress.com/2020/11/24/are-you-talking-to-heroku-redis-in-cleartext-or-ssl/ https://mislav.net/2013/07/ruby-openssl/

【问题讨论】:

可能相关:***.com/questions/65042551/… 【参考方案1】:

解决方案

为您的 Redis 客户端使用 OpenSSL::SSL::VERIFY_NONE

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 )

原因

Redis 6 需要 TLS 才能连接。但是,Heroku 支持解释说,他们管理从路由器级别到涉及自签名证书的应用程序级别的请求。事实证明,Heroku 在路由器级别终止 SSL,并通过 HTTP 从那里将请求转发到应用程序,而一切都在 Heroku 的防火墙和安全措施之后。


来源

https://ogirginc.github.io/en/heroku-redis-ssl-error https://devcenter.heroku.com/articles/securing-heroku-redis#connecting-directly-to-stunnel

【讨论】:

第二部分也可以放入 config/environment/production.rb 中。例如:config.cache_store = :redis_cache_store, url: ENV['REDIS_URL'], expires_in: 1.hour, ssl_params: verify_mode: OpenSSL::SSL::VERIFY_NONE 在我的应用程序中,添加初始化程序不起作用。我的解决方案是将 verify_mode 添加到 cable.yml 配置中。 还要确保您的redis 版本至少高于4.0.2。根据 Heroku 的说法,以下任何版本都会忽略 OpenSSL::SSL::VERIFY_NONE。这是我们使用旧版本 resque 和旧 resque 插件版本的情况。请参阅:devcenter.heroku.com/articles/…。 “此方法仅适用于redis gem 4.0.2 及以上版本。4.0.1 及以下版本忽略OpenSSL::SSL::VERIFY_NONE 作为验证模式,因此不能用于原生通过 SSL 连接 Heroku Redis。”跨度> 【参考方案2】:

如果您使用 ActionCable,您可能还需要将 verify_mode 添加到 `cable.yml 配置中:

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 %>

来源:https://github.com/chatwoot/chatwoot/issues/2420

【讨论】:

【参考方案3】:

如果您使用的是 Rails 5,您可以通过 cable.yml 文件将 won't be able to configure Redis 的 ssl_params 用于 ActionCable。相反,您可以在初始化程序中手动设置 redis_connector 属性,如下所示:

# frozen_string_literal: true

require "action_cable/subscription_adapter/redis"

ActionCable::SubscriptionAdapter::Redis.redis_connector = ->(_config) do
  Redis.new(...your options here...)
end

关于使用 OpenSSL::SSL::VERIFY_NONE 的含义以及为什么如果您使用 Heroku 可能没问题的更多背景信息:

使用OpenSSL::SSL::VERIFY_NONE 告诉客户端可以使用自签名证书,不会尝试验证证书是否由已知的证书颁发机构签名。

存在中间人攻击的风险。如果尝试与 Heroku Redis 通信的客户端未验证它遇到的 SSL 证书是否属于 Heroku(AKA,这些证书由已验证请求证书的实体实际上是 Heroku 的证书颁发机构签名),然后位于您的客户端和 Heroku Redis 之间的攻击者可以创建自己的自签名 SSL 证书并假装是 Heroku。这意味着它们可能会拦截您尝试发送到 Heroku Redis 的任何流量。

实际上,对于 Heroku dyno 与 Heroku Redis 对话来说,这可能不是一个现实的场景。

这是 Heroku 支持的引述:

MITM 攻击对托管主机提供商来说是不切实际的。这将是 坏演员很难在 dyno 和 Redis 实例之间找到 托管在 AWS 上。这是因为 EC2 实例在同一个 AZ 在任何时候都不应在 AWS 基础设施之外进行路由。这 在这种情况下,MITM 攻击只能由不良行为者执行 在托管服务提供商的设施内,因为 网络流量永远不会离开所述设施。

以下是来自 AWS 文档的一些 sn-ps,它们似乎证实了这一点:

https://aws.amazon.com/vpc/faqs/

问。两个实例通信时流量是否通过 Internet 使用公共 IP 地址,或者当实例与公共 AWS 服务端点?

没有。使用公共地址空间时,所有通信 AWS 中托管的实例和服务使用 AWS 的私有网络。 来自 AWS 网络的数据包,其目的地位于 AWS 网络保留在 AWS 全球网络上,进出的流量除外 AWS 中国区域。

此外,流经 AWS 全球网络的所有数据 互连我们的数据中心和区域是自动加密的 在它离开我们的安全设施之前在物理层。 还存在其他加密层;例如,所有 VPC 跨区域对等流量,以及客户或服务到服务 传输层安全 (TLS) 连接。

还有https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html

Amazon Virtual Private Cloud (Amazon VPC) 使您能够定义一个 AWS 内您自己的逻辑隔离区域中的虚拟网络 云,称为虚拟私有云 (VPC)。

当您创建 AWS 账户时,我们会在 每个地区

【讨论】:

以上是关于如何在 Sidekiq 上为 Redis 6 启用 TLS?的主要内容,如果未能解决你的问题,请参考以下文章

Rails 6 应用程序如何将 Sidekiq+Redis 用于 Hotwire/Stimulus,而将 DelayedJob 用于“工人工作”,例如电子邮件

在弹性beantalk中运行sidekiq时Redis连接超时错误

如何在 macos 上为 ffmpeg 启用 libx264

在 Windows 上为 PHP5.6.4 启用 CURL

阻止Sidekiq在测试中打印“(...)INFO:带有redis选项{}的Sidekiq客户端”

ActiveJob + Sidekiq 6.0.3:如何写入日志文件?