我刚刚开始学习Ruby,经过一些基本的事情,我试图理解在ruby中对REST服务进行REST调用。我可以毫不费力地向foursquare API提出请求。另一方面,对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>'
你可以请一些建议吗?谢谢
答案 0 :(得分:12)
你可以请一些建议吗?
这是一个更详细的答案,以及如何使用可悲的OpenSSL::SSL::VERIFY_NONE
以外的其他东西解决Ruby中的问题。
$ 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)发布。
如果再往前看,您会看到发行人的公钥(授权密钥标识符)与主题的公钥(主题密钥标识符)不同:
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-----
IF 您信任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
,因为它会删除弱/受伤/损坏的协议。但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破坏。
答案 1 :(得分:1)
如果您使用浏览器访问主持人,例如
> https://64.103.26.61/
你会看到你会得到同样的错误。此服务器上的证书无效,因为服务器响应的另一个主机名不是证书中写入的主机名。
如果您在Digicert Helpcenter输入服务器地址,则可以查找更复杂的说明。证书已发给msesandbox.cisco.com
。如果这是您尝试访问的地址,请使用此地址而不是IP。如果这是您的服务器,请更改响应名称
答案 2 :(得分:-4)
一个几乎总是错误的解决方法是忽略SSL证书检查:
:verify_ssl => OpenSSL::SSL::VERIFY_NONE
更新:这种解决方法几乎从不首选,因为它通常总结为一个容易忘记的明显的安全漏洞。在大多数情况下,如果您认为自己想要SSL而不检查证书,则可以通过生成自签名证书并锁定双方使用相同的证书来做得更好。