我一直试图将照片上传到我的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.rb
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
avatar_uploader.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)
答案 0 :(得分:4)
在@RodrigoM的调查帮助和你的问题更新后,一切都开始有意义了。实际上有两个不同的问题会导致您观察到的错误:
Aws.use_bundled_cert!
添加到初始值设定项according to the docs来解决的确切情况。但在这种情况下,它不起作用,因为即使此命令指示ruby openssl库从aws-sdk-core
gem CA bundle file,文件向受信任的商店添加各种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下工作的具体步骤,请参阅this SO question的 解决方案 部分。
此外,既然您正在使用分叉的aws-sdk-ruby
gem存储库,您也可以通过自己添加中间CA证书来更新ca-bundle.crt
file in your repo (根CA证书似乎已经存在于捆绑中)。为此,您需要执行以下操作:
将其转换为PEM格式(以DER格式下载)并使用以下openssl命令将其添加到cert包中:
openssl x509 -in DigiCertBaltimoreCA-2G2.crt -inform DER >> ca-bundle.crt
运行此命令后,您的ca-bundle.crt
应包含文件末尾的中间CA证书。
现在只需将此更新的捆绑文件推送到您的仓库, Aws.use_bundled_cert!
即可开始工作!
aws-sdk-ruby
gem上启动github问题,以便他们也在他们的回购中更新证书包...... 答案 1 :(得分:3)
您的Ruby代码,AWS SDK等都很好。这不是Ruby或SDK问题。您最初描述的错误消息以及您之后发布的OpenSSL连接日志都指出了问题的根本原因:OpenSSL框架中缺少根证书和/或未正确配置的CA证书捆绑包。进一步的线索是相同的代码适用于生产。它不是代码。
原始错误消息本身指向您指示的OpenSSL证书验证错误。堆栈跟踪还显示2.3.1 / lib / ruby / 2.3.0 / net / http.rb中的Ruby内部lib错误。这是利用OpenSSL框架的核心网络库。
openssl s_client
连接日志更清楚地显示了extact错误号和消息:
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)
之前,您的代码将无效。
此计算机上的OpenSSL设置不存在或未正确引用DigiCert Baltimore CA-2 CA证书。这是破碎或不完整的OpenSSL安装中非常常见的问题。您需要下载该证书,转换为PEM格式,将其保存在OpenSSL certs文件夹中的ca-certificate.crt文件中,然后在您的配置或环境变量SSL_CERT_FILE中引用该文件。
您可以看到针对根问题here
的良好解决方案注意:为了进一步确认此解决方案,您应该在生产服务器上运行openssl s_client
测试。您应该看到它在没有问题的情况下验证相同的CA.检查那里的OpenSSL配置和CA证书捆绑包配置,看看生产和开发环境之间存在差异的原因。
答案 2 :(得分:1)
此问题可能是由于证书无效所致。当您调用URL(API)
您可以先交叉验证证书。通过键入命令
openssl s_client -connect <url without https>:443
如果您在证书中发现任何问题。然后更新证书。证书管理者可以解决此问题。
答案 3 :(得分:0)
尝试使用这些宝石而非设置:
<强>的Gemfile 强>
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
<强>配置/ carrierwave.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
<强> * _ uploader.rb 强>
span {
width: 100px;
}
.input-group {
padding-right: 20px;
}
.tooltip {
position: absolute;
}