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 凝聚了许多人的心血,所以我建议您遵循它。

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

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

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

谢谢。

我在 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: 部分之后?

好的。我已添加 after_assets_precompile

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

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

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

这个问题有解决方案吗?我在尝试使用 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)

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

不过,我从未弄明白。

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

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

总之,谢谢。

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