![](/img/trans.png)
[英]certificate Error SSL_connect returned=1 errno=0 state=error: certificate verify failed
[英]Getting “SSL_connect returned=1 errno=0 state=error: certificate verify failed” when connecting to S3
我一直在嘗試將照片上傳到我的 AWS 存儲桶,但遇到了標題中提到的錯誤。 我知道這很可能與我的 OpenSSL 證書有關,但到目前為止我嘗試過的任何建議的解決方案都失敗了。
我在 OSX Yosemite 上使用 ruby 2.3.1、Rails 4.1.8、aws-sdk-core 2.3.4 和carrierwave 0.11.0 遇到了這個問題。
我已經嘗試了在這個類似問題上找到的所有可用內容,以及其他人(這個在 Windows 中): https : //github.com/aws/aws-sdk-core-ruby/issues/166#issuecomment-111603660
這是我的一些文件:
載波
CarrierWave.configure do |config| # required
config.aws_credentials = {
access_key_id: Rails.application.secrets.aws_access_key_id, # required
secret_access_key: Rails.application.secrets.aws_access_key, # required
region: 'eu-west-2' # optional, defaults to 'us-east-1'
}
config.aws_bucket = Rails.application.secrets.aws_bucket # required
config.fog_attributes = { 'Cache-Control' => "max-age=#{365.day.to_i}" } # optional, defaults to {}
end
頭像_上傳者.rb
class AvatarUploader < CarrierWave::Uploader::Base
storage :aws
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
編輯(更多信息):
stack trace:
Seahorse::Client::NetworkingError - SSL_connect returned=1 errno=0 state=error: certificate verify failed:
/Users/stevenharlow/.rbenv/versions/2.3.1/lib/ruby/2.3.0/net/http.rb:933:in `connect_nonblock'
/Users/stevenharlow/.rbenv/versions/2.3.1/lib/ruby/2.3.0/net/http.rb:933:in `connect'
/Users/stevenharlow/.rbenv/versions/2.3.1/lib/ruby/2.3.0/net/http.rb:863:in `do_start'
/Users/stevenharlow/.rbenv/versions/2.3.1/lib/ruby/2.3.0/net/http.rb:858:in `start'
/Users/stevenharlow/.rbenv/versions/2.3.1/lib/ruby/2.3.0/delegate.rb:83:in `method_missing'
aws-sdk-core (2.3.4) lib/seahorse/client/net_http/connection_pool.rb:292:in `start_session'
aws-sdk-core (2.3.4) lib/seahorse/client/net_http/connection_pool.rb:104:in `session_for'
aws-sdk-core (2.3.4) lib/seahorse/client/net_http/handler.rb:109:in `session'
嘗試的解決方案:
這是結果
CONNECTED(00000003)
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=*.s3-us-west-2.amazonaws.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
i:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root
---
<certificate info>
No client certificate CA names sent
---
SSL handshake has read 2703 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: <session-id>
Session-ID-ctx:
Master-Key: <master-key>
Key-Arg : None
Start Time: 1463697130
Timeout : 300 (sec)
Verify return code: 0 (ok)
在@RodrigoM 的調查幫助和您的問題更新下,這一切都開始變得有意義了。 實際上有兩個不同的問題會導致您觀察到的錯誤:
Aws.use_bundled_cert!
解決的確切情況Aws.use_bundled_cert!
根據文檔,到初始化程序。 但在這種情況下它不起作用,因為即使此命令指示 ruby openssl 庫將各種 CA 證書從aws-sdk-core
gem 的CA 捆綁文件添加到受信任的存儲,該文件也不包含正確的 CA 證書,如它本身已經快 2 歲了,已經過時了。 中間 CA 證書CN=DigiCert Baltimore CA-2 G2
已於 2015 年 12 月 8 日發布,所以難怪 CA 捆綁文件不包含它。現在,您有兩個選擇:
您可以嘗試將此中間 CA 證書(可能包括根 CA 證書( CN=Baltimore CyberTrust Root
))安裝到您的 openssl 受信任證書存儲中。 這應該使s_client
命令工作。 但是您可能仍然會遇到使用來自 ruby 代碼的這些可信證書的問題。 有關使其在 OSX 上的 ruby 下工作的具體步驟,請參閱此 SO 問題的解決方案部分。
此外,由於您無論如何都在使用分叉的aws-sdk-ruby
gem 存儲庫,您也可以通過自己添加中間 CA 證書來更新您的 repo 中的ca-bundle.crt
文件(根 CA 證書似乎已經存在於捆綁)。 為此,您需要執行以下操作:
將其轉換為 PEM 格式(以 DER 格式下載)並使用以下 openssl 命令將其添加到證書包中:
openssl x509 -in DigiCertBaltimoreCA-2G2.crt -inform DER >> ca-bundle.crt
運行此命令后,您的ca-bundle.crt
應在文件末尾包含中間 CA 證書。
現在只需將此更新的捆綁文件推送到您的存儲庫和Aws.use_bundled_cert!
應該開始工作了!
aws-sdk-ruby
gem 上啟動 github 問題,以便他們也更新其存儲庫中的證書包...你的 Ruby 代碼、AWS SDK 等都很好。 這不是 Ruby 或 SDK 問題。 您最初描述的錯誤消息以及您稍后發布的 OpenSSL 連接日志都指向問題的根本原因:OpenSSL 框架中缺少根證書和/或未正確配置 CA 證書包。 另一個線索是相同的代碼適用於生產。 它不是代碼。
正如您所指出的,原始錯誤消息本身指向 OpenSSL 證書驗證錯誤。 堆棧跟蹤還顯示 2.3.1/lib/ruby/2.3.0/net/http.rb 中的 Ruby 內部庫錯誤。 這是利用 OpenSSL 框架的核心網絡庫。
openssl s_client
連接日志更清楚地顯示了確切的錯誤號和消息:
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Baltimore CA-2 G2
verify error:num=20:unable to get local issuer certificate
在使用 openssl s-client 測試在 DigiCert Baltimore CA-2 CA 上獲得Verify return code: 0 (ok)
,您的代碼將無法工作。
DigiCert Baltimore CA-2 CA 證書不存在或該計算機上的 OpenSSL 設置未正確引用。 這是損壞或不完整的 OpenSSL 安裝中非常常見的問題。 您需要下載該證書,轉換為 PEM 格式,將其保存在 OpenSSL 證書文件夾中的 ca-certificate.crt 文件中,然后在您的配置或環境變量 SSL_CERT_FILE 中引用該文件。
您可以在此處查看解決根本問題的好方法
注意:要進一步確認此解決方案,您應該在生產服務器上運行openssl s_client
測試。 您應該會看到它在驗證相同的 CA 時沒有問題。 檢查那里的 OpenSSL 配置和 CA 證書捆綁配置,了解為什么您的生產和開發環境之間存在差異。
此問題可能是由於證書無效。 當您調用 URL(API) 時
您可以先交叉驗證證書。 通過鍵入命令
openssl s_client -connect <url without https>:443
如果您在證書中發現任何問題。 然后更新證書。 證書管理器可以解決這個問題。
嘗試使用這些gems和此設置:
文件
gem "carrierwave", "~> 0.11.0"
gem 'carrierwave-aws', "~> 1.0.1"
gem "unf", "~> 0.1.4"
配置/carrierwave.rb
require 'carrierwave'
require 'carrierwave/orm/activerecord'
CarrierWave.configure do |config|
config.storage = :aws # required
config.aws_bucket = Rails.application.secrets.aws_bucket # required
config.aws_acl = :public_read
config.aws_credentials = {
access_key_id: Rails.application.secrets.aws_access_key_id, # required
secret_access_key: Rails.application.secrets.aws_access_key # required
}
config.aws_attributes = {
cache_control: 'max-age=31536000',
expires: 1.year.from_now.httpdate
}
end
*_uploader.rb
storage :aws
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Use Heroku's temp folder for uploads
def cache_dir
"#{Rails.root}/tmp/uploads"
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.