SSLError: hostname "W.X.Y.Z" does not match the server certificate
SSLError: hostname "W.X.Y.Z" does not match the server certificate
我刚开始学习 Ruby,在学习了一些基础知识后,我试图了解如何对 ruby 中的服务进行 REST 调用。我可以毫不费力地向 foursquare API 发出 get 请求。另一方面,调用 Cisco CMX API 会出错。我的 ruby 版本是 2.1.2。我在网上搜索了很多解决方案,但仍然遇到问题。这是我运行的 shell 命令。
工作一
$resclient
>> RestClient.get 'https://api.foursquare.com/v2/venues/search?ll=40.7,-74&oauth_token=0ZDO1JMJ0PW2QTCDK50OGZ21UENHZ0Y3KIDQZJLLURTQNRQ2&v=20150106'
这给出了错误
$restclient
>> RestClient.get 'https://learning:learning@64.103.26.61/api/contextaware/v1/maps/.json'
我的错误日志:
OpenSSL::SSL::SSLError: hostname "64.103.26.61" does not match the server certificate
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/openssl/ssl.rb:139:in `post_connection_check'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:922:in `connect'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:863:in `do_start'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:852:in `start'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:413:in `transmit'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:176:in `execute'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:41:in `execute'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient.rb:65:in `get'
from (irb):3
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/bin/restclient:93:in `<top (required)>'
from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `load'
from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `<main>'
能给点建议吗?谢谢
如果您使用浏览器访问主机,例如
> https://64.103.26.61/
你会看到你会得到同样的错误。此服务器上的证书无效,因为服务器响应的主机名与证书中写入的主机名不同。
如果您在 Digicert Helpcenter 输入服务器地址,您可以查找更复杂的描述。证书已颁发给 msesandbox.cisco.com
。如果这是您要访问的地址,请使用此地址而不是 IP。如果这是您的服务器,请更改响应名称
一个几乎总是不好的解决方法是忽略 SSL 证书检查:
:verify_ssl => OpenSSL::SSL::VERIFY_NONE
更新:这种解决方法几乎从来都不是首选,因为它通常总结为一个明显的安全漏洞,很容易被遗忘。在大多数情况下,如果您认为不需要检查证书就需要 SSL,您最好生成一个自签名证书并锁定双方以使用相同的证书。
Could you please give some advise?
这里有一个更详细的答案,以及如何解决 Ruby 中的问题,而不是可怜的 OpenSSL::SSL::VERIFY_NONE
。
$ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
...
Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com
...
X509v3 Subject Alternative Name:
DNS:msesandbox.cisco.com
因此设备的 DNS 名称为 msesandbox.cisco.com。 nslookup
告诉你它是一个很好的主机名:
$ nslookup msesandbox.cisco.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: msesandbox.cisco.com
Address: 64.103.26.61
因此,您要做的第一件事就是通过其 DNS 名称而不是 IP 地址连接到它。
如果您为 cisco.com
域颁发证书(或可以提出请求),那么您可以要求将 IP 地址 64.103.26.61 添加为 主题备用名称 (SAN )。所以证书中会有两个SAN。
现在,如果您返回 openssl
命令:
$ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify error:num=19:self signed certificate in certificate chain
...
Issuer: C=US, O=HydrantID (Avalanche Cloud Corporation), CN=HydrantID SSL ICA G2
...
Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com
您会看到发行人和主题不同。这意味着这是 不是 自签名证书。证书由 HydrantID (Avalanche Cloud Corporation).
颁发
如果你看得更远,你会看到发行者的 public 密钥(权威密钥标识符)与主题的 public 密钥(主题密钥标识符)不同:
X509v3 Authority Key Identifier:
keyid:98:6A:B6:2D:2E:BF:A7:AA:9F:F6:F7:D6:09:AF:D5:8B:57:F9:8A:B7
...
X509v3 Subject Key Identifier:
B5:3D:50:53:0A:A2:06:9E:9A:29:89:7A:AB:96:90:FE:9D:6B:57:A0
同样,它不是自签名的。
如果你再次回到 OpenSSL 命令,你会看到发行者是 HydrantID SSL ICA G2
,它的发行者是 QuoVadis Root CA2 G3
:
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2
verify return:1
depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com
verify return:1
表示QuoVadis Root CA2 G3
发出HydrantID SSL ICA G2
;并且 HydrantID SSL ICA G2
发布了 msesandbox.cisco.com
。 QuoVadis Root CA2 G3
是食物链的顶端。
您可以从 QuoVadis CA Certificate Download 获取 QuoVadis Root CA2 G3
:
$ curl -O -J -L https://www.quovadisglobal.bm/Repository/~/media/Files/Roots/quovadis_rca2g3_der.ashx
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1380 100 1380 0 0 1808 0 --:--:-- --:--:-- --:--:-- 5726
curl: Saved to filename 'quovadis_rca2g3_der.cer'
$ openssl x509 -in quovadis_rca2g3_der.cer -inform DER -out quovadis-ca.pem -outform PEM
$ cat quovadis-ca.pem
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
...
-----END CERTIFICATE-----
如果 您信任 QuoVadis 对设备进行认证,那么:
$ openssl s_client -connect msesandbox.cisco.com:443 -CAfile quovadis-ca.pem
CONNECTED(00000003)
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2
verify return:1
depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com
verify return:1
...
Start Time: 1420616960
Timeout : 300 (sec)
Verify return code: 0 (ok)
注意 OpenSSL 使用 Verify return code: 0 (ok)
完成。那告诉你你有一个很好的链条。 OpenSSL 不执行主机名匹配,但我们已经知道证书中的主机名是好的。
现在,Ruby 代码。您需要做的就是将 CA 插入 Ruby:
#!/usr/bin/ruby
require 'net/http'
require 'net/https'
require 'openssl'
uri = URI('https://msesandbox.cisco.com:443')
options_mask = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | OpenSSL::SSL::OP_NO_COMPRESSION
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = File.join(File.dirname(__FILE__), "quovadis-ca.pem")
# http.ssl_options = options_mask
end
response = http.request request
这里是 运行:
$ ./Connect-Test.rb
$
没有例外,也没有 OpenSSL::SSL::VERIFY_NONE
。
您应该尝试使用 options_mask
,因为它删除了 weak/wounded/broken 协议。但是 Ruby 有时如此破碎且没有记录,我从来没有能够让它工作。
我能够通过 OpenSSL 在 HydrantID SSL ICA G2
和 QuoVadis Root CA2 G3
中建立信任(这意味着我从 OpenSSL 获得了 Verify Result 0 (OK)
)。但是 Ruby 只能处理 QuoVadis Root CA2 G3
(它无法建立到 HydrantID SSL ICA G2
的链)。更多 Ruby 破碎。
我刚开始学习 Ruby,在学习了一些基础知识后,我试图了解如何对 ruby 中的服务进行 REST 调用。我可以毫不费力地向 foursquare API 发出 get 请求。另一方面,调用 Cisco CMX API 会出错。我的 ruby 版本是 2.1.2。我在网上搜索了很多解决方案,但仍然遇到问题。这是我运行的 shell 命令。
工作一
$resclient
>> RestClient.get 'https://api.foursquare.com/v2/venues/search?ll=40.7,-74&oauth_token=0ZDO1JMJ0PW2QTCDK50OGZ21UENHZ0Y3KIDQZJLLURTQNRQ2&v=20150106'
这给出了错误
$restclient
>> RestClient.get 'https://learning:learning@64.103.26.61/api/contextaware/v1/maps/.json'
我的错误日志:
OpenSSL::SSL::SSLError: hostname "64.103.26.61" does not match the server certificate
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/openssl/ssl.rb:139:in `post_connection_check'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:922:in `connect'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:863:in `do_start'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:852:in `start'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:413:in `transmit'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:176:in `execute'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient/request.rb:41:in `execute'
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/lib/restclient.rb:65:in `get'
from (irb):3
from /Users/apple/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.7.2/bin/restclient:93:in `<top (required)>'
from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `load'
from /Users/apple/.rbenv/versions/2.1.2/bin/restclient:23:in `<main>'
能给点建议吗?谢谢
如果您使用浏览器访问主机,例如
> https://64.103.26.61/
你会看到你会得到同样的错误。此服务器上的证书无效,因为服务器响应的主机名与证书中写入的主机名不同。
如果您在 Digicert Helpcenter 输入服务器地址,您可以查找更复杂的描述。证书已颁发给 msesandbox.cisco.com
。如果这是您要访问的地址,请使用此地址而不是 IP。如果这是您的服务器,请更改响应名称
一个几乎总是不好的解决方法是忽略 SSL 证书检查:
:verify_ssl => OpenSSL::SSL::VERIFY_NONE
更新:这种解决方法几乎从来都不是首选,因为它通常总结为一个明显的安全漏洞,很容易被遗忘。在大多数情况下,如果您认为不需要检查证书就需要 SSL,您最好生成一个自签名证书并锁定双方以使用相同的证书。
Could you please give some advise?
这里有一个更详细的答案,以及如何解决 Ruby 中的问题,而不是可怜的 OpenSSL::SSL::VERIFY_NONE
。
$ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
...
Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com
...
X509v3 Subject Alternative Name:
DNS:msesandbox.cisco.com
因此设备的 DNS 名称为 msesandbox.cisco.com。 nslookup
告诉你它是一个很好的主机名:
$ nslookup msesandbox.cisco.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: msesandbox.cisco.com
Address: 64.103.26.61
因此,您要做的第一件事就是通过其 DNS 名称而不是 IP 地址连接到它。
如果您为 cisco.com
域颁发证书(或可以提出请求),那么您可以要求将 IP 地址 64.103.26.61 添加为 主题备用名称 (SAN )。所以证书中会有两个SAN。
现在,如果您返回 openssl
命令:
$ openssl s_client -connect 64.103.26.61:443 | openssl x509 -text -noout
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify error:num=19:self signed certificate in certificate chain
...
Issuer: C=US, O=HydrantID (Avalanche Cloud Corporation), CN=HydrantID SSL ICA G2
...
Subject: C=US, ST=CA, L=San Jose, O=Cisco Systems, Inc., CN=msesandbox.cisco.com
您会看到发行人和主题不同。这意味着这是 不是 自签名证书。证书由 HydrantID (Avalanche Cloud Corporation).
颁发如果你看得更远,你会看到发行者的 public 密钥(权威密钥标识符)与主题的 public 密钥(主题密钥标识符)不同:
X509v3 Authority Key Identifier:
keyid:98:6A:B6:2D:2E:BF:A7:AA:9F:F6:F7:D6:09:AF:D5:8B:57:F9:8A:B7
...
X509v3 Subject Key Identifier:
B5:3D:50:53:0A:A2:06:9E:9A:29:89:7A:AB:96:90:FE:9D:6B:57:A0
同样,它不是自签名的。
如果你再次回到 OpenSSL 命令,你会看到发行者是 HydrantID SSL ICA G2
,它的发行者是 QuoVadis Root CA2 G3
:
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2
verify return:1
depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com
verify return:1
表示QuoVadis Root CA2 G3
发出HydrantID SSL ICA G2
;并且 HydrantID SSL ICA G2
发布了 msesandbox.cisco.com
。 QuoVadis Root CA2 G3
是食物链的顶端。
您可以从 QuoVadis CA Certificate Download 获取 QuoVadis Root CA2 G3
:
$ curl -O -J -L https://www.quovadisglobal.bm/Repository/~/media/Files/Roots/quovadis_rca2g3_der.ashx
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1380 100 1380 0 0 1808 0 --:--:-- --:--:-- --:--:-- 5726
curl: Saved to filename 'quovadis_rca2g3_der.cer'
$ openssl x509 -in quovadis_rca2g3_der.cer -inform DER -out quovadis-ca.pem -outform PEM
$ cat quovadis-ca.pem
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
...
-----END CERTIFICATE-----
如果 您信任 QuoVadis 对设备进行认证,那么:
$ openssl s_client -connect msesandbox.cisco.com:443 -CAfile quovadis-ca.pem
CONNECTED(00000003)
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = US, O = HydrantID (Avalanche Cloud Corporation), CN = HydrantID SSL ICA G2
verify return:1
depth=0 C = US, ST = CA, L = San Jose, O = "Cisco Systems, Inc.", CN = msesandbox.cisco.com
verify return:1
...
Start Time: 1420616960
Timeout : 300 (sec)
Verify return code: 0 (ok)
注意 OpenSSL 使用 Verify return code: 0 (ok)
完成。那告诉你你有一个很好的链条。 OpenSSL 不执行主机名匹配,但我们已经知道证书中的主机名是好的。
现在,Ruby 代码。您需要做的就是将 CA 插入 Ruby:
#!/usr/bin/ruby
require 'net/http'
require 'net/https'
require 'openssl'
uri = URI('https://msesandbox.cisco.com:443')
options_mask = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 | OpenSSL::SSL::OP_NO_COMPRESSION
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = File.join(File.dirname(__FILE__), "quovadis-ca.pem")
# http.ssl_options = options_mask
end
response = http.request request
这里是 运行:
$ ./Connect-Test.rb
$
没有例外,也没有 OpenSSL::SSL::VERIFY_NONE
。
您应该尝试使用 options_mask
,因为它删除了 weak/wounded/broken 协议。但是 Ruby 有时如此破碎且没有记录,我从来没有能够让它工作。
我能够通过 OpenSSL 在 HydrantID SSL ICA G2
和 QuoVadis Root CA2 G3
中建立信任(这意味着我从 OpenSSL 获得了 Verify Result 0 (OK)
)。但是 Ruby 只能处理 QuoVadis Root CA2 G3
(它无法建立到 HydrantID SSL ICA G2
的链)。更多 Ruby 破碎。