Excon SSL 验证问题:ONEBOX

大家好,

我刚搭建并开始测试一个 Discourse 服务器,目前运行状况良好。但我遇到了一个问题:Onebox 功能无法正常工作,我认为这是由于 SSL 检测过滤器导致 excon gem 无法验证证书。我已下载了自定义根证书,并将其添加到主机的 /etc/ssl/certs 目录中,甚至尝试将其添加到容器内(用于测试),但均无济于事。每当我粘贴用于嵌入的 URL 时,/log/rails/production.log 中仍会出现以下错误:

Failed to onebox [youtube url] SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate) (OpenSSL::SSL::SSLError) Unable to verify certificate.

错误信息提到需要修改 excon 的默认配置以指向不同的 ssl_path,但我不确定如何安全地执行此操作,同时仍能允许 Discourse 正常更新。请问有人能建议如何确保 excon 将自定义根证书视为有效吗?是否可以在 app.yml 中添加 rails -r exec 命令来实现?

非常感谢,

Glenn。

哪个 URL 显示了问题?您使用的是 Discourse 官方基于 Docker 的安装方式吗?

看起来默认情况下 excon 会捆绑自己的证书包,但由于其他人也遇到了类似问题,他是否已添加了在环境变量中配置该功能的能力?如果证书配置正确,它将使用系统证书。

这可能需要哈希链接才能生效。请尝试以下操作,看看是否能解决问题:

  • 同时执行以下两项操作:
    • 将您的自定义证书添加到容器内的 /etc/ssl/certs 目录中

    • 添加哈希链接,例如:

      ln -s my_custom_cert.pem /etc/ssl/certs/$(openssl x509 -hash -noout -in /etc/ssl/certs/my_custom_cert.pem).0
      

谢谢,Michael。

我设置了环境变量并创建了哈希值,现在看不到明显的 SSL 错误,但 Onebox 仍然没有任何反应。不知道 Jeff 对我可能哪里做错了有什么建议吗?@codinghorror

不过我担心在容器内部进行的更改在重建时会被销毁,所以我不确定这里最好的方法是什么。

Glenn。

它可能缓存了失败结果,但让我们一次测试一件事。

你不需要添加环境变量,但你可以通过执行以下操作来检查添加证书是否生效,例如:

root:~# /var/discourse/launcher enter app
root@app:/var/www/discourse# rails console
[1] pry(main)> Net::HTTP.get URI 'https://meta.discourse.org/about.json'

如果你得到了结果(而之前没有),那就说明证书已正确安装。然后,你可以在容器定义中添加命令,以便在每次重建时安装该证书,从而确保持久化。

谢谢 Michael,rails 控制台命令运行正常,它成功下载了你链接的 JSON 文件。

我不确定之前是否无法运行,但我之前已将根证书安装到 /etc/ssl/certs/,问题仍然存在。

我在容器中运行了 export SSL_CERT_DIR=“/etc/ssl/certs/”,之后 SSL 错误似乎消失了。至少我在 production.log 中不再看到任何相关错误。

谢谢,

Glenn。

实际上,我想我现在可能已经找到问题所在了。这应该是一个与企业过滤器相关的身份验证提示。我在控制台中使用 Net::HTTP.get 方法,通过 YouTube 的 oEmbed URI 请求嵌入 JSON,结果却返回了一个身份验证的 HTML 文档。所以我认为这就是目前的障碍所在。非常感谢,Michael。

你是否也创建了符号链接?这是非常关键的一步。

若要确保证书永久生效,请修改 app.yml 文件,添加或修改 hooks 部分,使其类似于以下内容:

hooks:
  before_code:
    - file:
        path: /etc/ssl/certs/custom-root.crt
        chmod: 644
        contents: |
          -----BEGIN CERTIFICATE-----
          …
          -----END CERTIFICATE-----
    - exec:
        cmd:
          - bash -c "ln -s custom-root.crt /etc/ssl/certs/$(openssl x509 -hash -noout -in /etc/ssl/certs/custom-root.crt).0"

啊,这很可能是我们无法通过在 app.yml 文件中添加内容来解决的问题。