如何在 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_file
、cert
和key
。 问题是如何为 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