SSL_connect 返回=1 errno=0 peeraddr=162.243.189.2:443 状态=错误:证书验证失败 (主机名不匹配)

我的 Digital Ocean Droplet 空间快用完了,所以我想把上传的文件移到 Digital Ocean Space。

这是我的设置……

我看到了这个…

…还有这个…

但我的设置显示在管理界面中,所以我认为这可能不是过时的,只是需要正确配置我的设置。

我看到了这个…

…但管理区域不允许我将“s3 upload bucket”留空,所以我不知道这是否相关。那似乎也只适用于使用 AWS S3 的情况。我尝试在我的 DO Space 中创建一个文件夹并使用该文件夹名。我尝试使用一个不存在的文件夹名称,以防它需要自己创建。这些都不起作用。

我看到了这个…

…但我远非专家,所以我回避了它。

现在我已无计可施,不确定我是否接近成功,只需要正确的设置配置,或者我是否完全遗漏了什么,根本没有接近。

任何帮助将不胜感激。谢谢。

另外,我也尝试过使用 DO API 凭证,例如……

不确定它应该匹配什么,所以我在这方面也有些困惑。

不,它们没有。虽然您可以在 UI 中配置 S3 端点,但我们在配置 app.yml 文件时仅测试和验证了使用 S3 克隆(如 Digital Ocean 提供)的情况。

配置兼容 S3 的对象存储提供商以上传文件 wiki 凝聚了许多人的心血,所以我建议您遵循它。

4 个赞

好吧,Falco 比我快一步,但这是我刚才说的……

不。你需要按照 Configure an S3 compatible object storage provider for uploads 的说明,将设置放入你的 app.yml 文件中。

你需要一个真正的 CDN,比如 bunny.net。我不认为 Cloudflare 可以。

1 个赞

谢谢。

我在 app.yml 中没有看到 DISCOURSE_S3 设置部分。我只需要为每个设置添加一行吗?还是 sudo 命令就是做这个的?

我不太清楚在哪里运行或放置这些 sudo 命令。不清楚这是否是一个一次性的命令行项目来添加它,还是必须将其放入 app.yml 中以便始终考虑到它。

sudo 命令是放在 app.yml 区域还是只放 DISCOURSE_S3 设置行?


使用 DO Spaces 时,我是否只需将 DISCOURSE_S3_REGION 留空?


我必须使用 CDN 吗?我们的流量非常低。用户群体很小。我真的想尽可能地减少需要处理的环节。

这个…

…放在…的**# plugins to here**下面…

hooks:

…区域,在…

after_code: 部分之后?

1 个赞

好的。我已添加 after_assets_precompile

我已重新构建,但仍然看不到 S3 部分。

我需要自己创建一个吗?
设置放在哪里是否重要?

如指南中所述,它们必须放在 env: 部分下,与其他 DISCOURSE_ 设置一起:

2 个赞

这个问题有解决方案吗?我在尝试使用 Oracle Cloud Storage 时遇到了同样的错误。

我遵循了 wiki 中的说明,在 app.yml 中进行了设置。我尝试使用 s3cmd 手动进行正确的连接。但是,在上传图片时,我收到了相同的错误消息。

消息(报告了 4 个副本)
作业异常:SSL_connect 返回=1 errno=0 peeraddr=134.70.128.1:443 状态=错误:证书验证失败(主机名不匹配)
回溯
/usr/local/lib/ruby/3.2.0/net/protocol.rb:46:in `connect_nonblock'
/usr/local/lib/ruby/3.2.0/net/protocol.rb:46:in `ssl_socket_connect'
/usr/local/lib/ruby/3.2.0/net/http.rb:1342:in `connect'
/usr/local/lib/ruby/3.2.0/net/http.rb:1248:in `do_start'
/usr/local/lib/ruby/3.2.0/net/http.rb:1243:in `start'
/usr/local/lib/ruby/3.2.0/delegate.rb:87:in `method_missing'
aws-sdk-core-3.130.2/lib/seahorse/client/net_http/connection_pool.rb:307:in `start_session'
aws-sdk-core-3.130.2/lib/seahorse/client/net_http/connection_pool.rb:100:in `session_for'
aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:128:in `session'
aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:76:in `transmit'
aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:50:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/content_length.rb:24:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:85:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:132:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:63:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_host_id.rb:17:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/xml/error_handler.rb:10:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/transfer_encoding.rb:26:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/helpful_socket_errors.rb:12:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:110:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/redirects.rb:20:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:360:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:394:in `retry_request'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:382:in `retry_if_possible'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:371:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:394:in `retry_request'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:382:in `retry_if_possible'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:371:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:394:in `retry_request'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:382:in `retry_if_possible'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:371:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/http_checksum.rb:19:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/endpoint_pattern.rb:30:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:67:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:136:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/bucket_dns.rb:35:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:41:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/expect_100_continue.rb:22:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb:26:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/arn.rb:62:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/rest/handler.rb:10:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/recursion_detection.rb:18:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/user_agent.rb:13:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/endpoint.rb:47:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_validator.rb:26:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/arn.rb:88:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/raise_response_errors.rb:16:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:27:in `call'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:56:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:111:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:22:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:71:in `call'
aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/plugins/response_target.rb:24:in `call'
aws-sdk-core-3.130.2/lib/seahorse/client/request.rb:72:in `send_request'
aws-sdk-s3-1.114.0/lib/aws-sdk-s3/client.rb:10921:in `put_bucket_policy'
/var/www/discourse/lib/s3_inventory.rb:183:in `update_bucket_policy'
/var/www/discourse/app/jobs/regular/update_s3_inventory.rb:16:in `block in execute'
/var/www/discourse/app/jobs/regular/update_s3_inventory.rb:14:in `each'
/var/www/discourse/app/jobs/regular/update_s3_inventory.rb:14:in `execute'
/var/www/discourse/app/jobs/base.rb:292:in `block (2 levels) in perform'
rails_multisite-5.0.0/lib/rails_multisite/connection_management.rb:82:in `with_connection'
/var/www/discourse/app/jobs/base.rb:279:in `block in perform'
/var/www/discourse/app/jobs/base.rb:275:in `each'
/var/www/discourse/app/jobs/base.rb:275:in `perform'
sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job'
sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:134:in `call'
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke'
sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process'
sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local'
sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
sidekiq-6.5.12/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats'
sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call'
sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global'
sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch'
sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare'
sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch'
sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process'
sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one'
sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run'
sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog'
sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread'

提前感谢!

附注:不仅是 Oracle Cloud Service,还有另一个国内服务提供商。

您是不是用了错误的存储桶名称来访问它?

您使用的是哪个存储桶提供商?

如上所述:我正在尝试使用 Oracle Cloud Storage。并且我已通过 s3cmd 工具使用同一帐户进行了手动检查。

而且不可能弄错名称,因为我只是复制粘贴。

我检查了 S3 端点的 DNS:

dig axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com

;; <<>> DiG 9.18.18-0ubuntu0.22.04.1-Ubuntu <<>> axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63008
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com. IN A

;; ANSWER SECTION:
axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com. 258 IN CNAME compat.objectstorage.ap-singapore-1.oci.oraclecloud.com.
compat.objectstorage.ap-singapore-1.oci.oraclecloud.com. 258 IN	CNAME objectstorage.ap-singapore-1.oci.oraclecloud.com.
objectstorage.ap-singapore-1.oci.oraclecloud.com. 174 IN A 134.70.128.1

;; AUTHORITY SECTION:
ap-singapore-1.oci.oraclecloud.com. 258	IN SOA	ns1.p200.dns.oraclecloud.net. hostmaster.ap-singapore-1.oci.oraclecloud.com. 682052 3600 900 31536000 1800

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Sat Nov 04 18:58:03 +07 2023
;; MSG SIZE  rcvd: 252

并使用目标地址:objectstorage.ap-singapore-1.oci.oraclecloud.com 而不是原始名称:axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com

然后我在 s3cmd 工具中得到了与 Discourse 显示完全相同的错误消息:

请稍候,正在尝试列出所有存储桶...
错误:测试失败:[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:主机名不匹配,证书对 'objectstorage.ap-singapore-1.oci.oraclecloud.com' 无效。(_ssl.c:1007)

我对此问题没有任何经验。 :frowning:

所以问题可能出在这里:

有什么办法可以解决这个问题吗?谢谢!

使用与证书匹配的名称。

经过多次尝试,我仍然收到相同的错误消息。我手动检查了证书和主机名,并使用了正确的格式来仔细查看正确的证书,但都没有成功。

我的端点: <namespace>.<region>.compat.objectstorage.oraclecloud.com
证书的通用名称 (CN): *.compat.objectstorage.<region>.oraclecloud.com

我可以使用 s3cmd 工具连接。但无法使用相同的配置为 discourse 设置 S3 上传。

错误消息: SSL_connect returned=1 errno=0 peeraddr=134.70.128.1:443 state=error: certificate verify failed (Hostname mismatch)

我想尝试另一种方法,通过在 Ruby 环境中设置(到处搜索后):

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

但如何在 discourse 中设置这个?拜托!

这是一个坏主意,因为它会破坏 X509 证书提供的许多保护。

你能展示一下你这里非秘密的设置吗?请注意 Oracle Cloud 不受支持,但我们仍然会快速查看是否有明显错误。

是的,您在关闭它时是对的。我想找到原因,以便在 ruby 库出错时提交一个 PR。

我的设置非常简单,只是尝试将图像上传到 S3 兼容存储。

  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: <region>
  DISCOURSE_S3_ENDPOINT: https://<namespace>.compat.objectstorage.<region>.oraclecloud.com
  DISCOURSE_S3_ACCESS_KEY_ID: <access_key_id>
  DISCOURSE_S3_SECRET_ACCESS_KEY: <access_key>
  DISCOURSE_S3_BUCKET: <bucket_name>

Oracle Cloud Storage 对端点地址有一些格式要求。但无论我尝试哪种格式,都会出现我上面显示的相同错误消息。

SSL_connect returned=1 errno=0 peeraddr=134.70.128.1:443 state=error: certificate verify failed (Hostname mismatch)

我上面使用的格式,我已经检查了证书,在我看来是正确的:

正如我之前所说,我使用此设置通过 s3cmd 工具正常连接。非常感谢!

好的,我在 ssl_socket_connect 的开头添加了一个 binding.pry,当我尝试使用这些设置时,我看到:

→ DISCOURSE_USE_S3=true DISCOURSE_S3_REGION=ap-singapore-1 DISCOURSE_S3_ENDPOINT=https://axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com DISCOURSE_S3_ACCESS_KEY_ID=foo DISCOURSE_S3_SECRET_ACCESS_KEY=bar DISCOURSE_S3_BUCKET=bucketname bin/rails c
Loading development environment (Rails 7.0.7)
[1] pry(main)> s3 = S3Helper.build_from_config; s3.list

From: /home/michael/.rvm/gems/ruby-3.2.2@discourse/gems/net-protocol-0.2.2/lib/net/protocol.rb:42 Net::Protocol#ssl_socket_connect:

    40: def ssl_socket_connect(s, timeout)
    41:   binding.pry
 => 42:   if timeout
    43:     while true
    44:       raise Net::OpenTimeout if timeout <= 0
    45:       start = Process.clock_gettime Process::CLOCK_MONOTONIC
    46:       # to_io is required because SSLSocket doesn't have wait_readable yet
    47:       case s.connect_nonblock(exception: false)
    48:       when :wait_readable; s.to_io.wait_readable(timeout)
    49:       when :wait_writable; s.to_io.wait_writable(timeout)
    50:       else; break
    51:       end
    52:       timeout -= Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
    53:     end
    54:   else
    55:     s.connect
    56:   end
    57: end

[1] pry(#<Net::HTTP>)> s.hostname
=> "bucketname.axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com"

所以实际连接的主机名是 bucketname.axhjdarc4cuy.compat.objectstorage.ap-singapore-1.oraclecloud.com,这与 *.compat.objectstorage.ap-singapore-1.oraclecloud.com 不匹配,所以错误是正确的。

不幸的是,OCI 不支持 这种风格的访问:

在您的应用程序中使用基于路径的访问。不支持虚拟主机风格的访问(将存储桶访问为 {bucketnamespace}.compat.objectstorage.{region}.oraclecloud.com [sic])。

相反,Discourse 只支持虚拟主机风格的访问({bucketname}.{namespace}.compat.objectstorage.{region}.oraclecloud.com.)。

我们几年前移除了 可能使其生效的设置,因为它支持不佳(参见提交消息)。

要使其正常工作并不简单,需要复杂的开发和测试来添加此支持。

这里有危险。

(参考:S3 Path Style Access)

4 个赞

解释得很清楚。非常感谢!

1 个赞

不过,我从未弄明白。

找到了他所指的内容,但当我复制粘贴文本时,它会反转大小写。我放弃了,没有再继续。明年可能会再试一次。

我希望在此期间有人能弄明白,并根据我的计划更好地记录设置。

总之,谢谢。

我遇到了这个问题并已修复,我的解决方案是,在我设置时,我的邮件服务器未经过 SSL 验证,但我的域名提供商确实为我提供了一个经过 SSL 验证的邮件服务器,所以我更换了它们。