WWW :: Mechanize SSL连接尝试因https get而失败

时间:2018-01-06 18:37:41

标签: perl www-mechanize

我正在尝试使用WWW :: Mechanize检索网页,并且SSL连接错误失败。我该如何解决这个问题?我在Windows 10 x64上运行ActivePerl 5.20.2。

这是我执行的脚本:

perl -MIO::Socket::SSL=debug4 -MWWW::Mechanize -e 'WWW::Mechanize->new()->get("https://fundresearch.fidelity.com/mutual-funds/fees-and-prices/316343201")'

输出如下:

DEBUG: .../IO/Socket/SSL.pm:2649: new ctx 98842176
DEBUG: .../IO/Socket/SSL.pm:562: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:564: socket connected
DEBUG: .../IO/Socket/SSL.pm:586: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:619: using SNI with hostname fundresearch.fidelity.com
DEBUG: .../IO/Socket/SSL.pm:654: request OCSP stapling
DEBUG: .../IO/Socket/SSL.pm:673: set socket to non-blocking to enforce timeout=180
DEBUG: .../IO/Socket/SSL.pm:686: call Net::SSLeay::connect
DEBUG: .../IO/Socket/SSL.pm:689: done Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:699: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:709: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:729: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:686: call Net::SSLeay::connect
DEBUG: .../IO/Socket/SSL.pm:2552: did not get stapled OCSP response
DEBUG: .../IO/Socket/SSL.pm:2505: ok=0 cert=102327360
DEBUG: .../IO/Socket/SSL.pm:689: done Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:692: SSL connect attempt failed

DEBUG: .../IO/Socket/SSL.pm:692: local error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:695: fatal SSL error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
DEBUG: .../lib/Net/HTTPS.pm:69: ignoring less severe local error 'IO::Socket::IP configuration failed', keep 'SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed'
DEBUG: .../IO/Socket/SSL.pm:2682: free ctx 98842176 open=98842176
DEBUG: .../IO/Socket/SSL.pm:2687: free ctx 98842176 callback
DEBUG: .../IO/Socket/SSL.pm:2694: OK free ctx 98842176
Error GETing https://fundresearch.fidelity.com/mutual-funds/fees-and-prices/316343201: Can't connect to fundresearch.fidelity.com:443 at -e line 1.

我能够使用curl成功检索网页。

2 个答案:

答案 0 :(得分:5)

TL; DR:升级Perl或至少Mozilla :: CA模块或使用SSL_ca_file与您自己的信任存储区。

我怀疑问题是因为您使用的是旧版本的Perl,特别是此Perl附带的旧版Mozilla :: CA模块。查看此站点的证书链(例如在SSLLabs),您会发现它看起来如下:

[0] CN=fundresearch.fidelity.com
[1] CN=Entrust Certification Authority - L1K
[2] CN=Entrust Root Certification Authority - G2   -- selfsigned

此信任链中的最后一个证书是自签名的,即此证书中的信任来自证书本身。这显然是对服务器的错误配置,这就是验证信任链时忽略此证书的原因。

CN=Entrust Certification Authority - L1K的颁发者CA是CN=Entrust Root Certification Authority - G2,即完全由服务器发送但被忽略的证书,因为不应该仅依赖于服务器发送的信任。这意味着需要在本地信任库中存在此根CA的实例。

现代浏览器和操作系统在信任库中都有此CA,这就是您可以使用浏览器访问此站点的原因。但是,WWW :: Mechanize(基于LWP :: UserAgent)不使用系统信任存储(至少在Windows上)。相反,信任存储由Mozilla :: CA模块提供,该模块不时从Mozilla(即Firefox)获取信任存储的副本。

根据您的Perl发行版的版本,您可能使用Mozilla :: CA的版本20141217。此版本尚未将CA Entrust Root Certification Authority - G2包含为受信任的版本。此CA仅包含在下一个version 20150826中。由于CA不被视为可信任,因此验证将失败。

有几种可能的修复方法。

  • 一个是升级Perl的版本。这可能是最好的选择,因为这还包括在处理多个可能的信任路径时对OpenSSL的修复 - 这是您可能在其他站点遇到的问题(有关详细信息,请参阅here)。
  • 另一种方法是升级Mozilla :: CA模块。但是,如果您仍然使用上述OpenSSL问题未修复的旧Perl,这实际上可能会导致某些站点出现问题。
  • 或者您可以将the missing certificate添加到您的cacert.pem(由Mozilla :: CA提供的那个)。
  • 最后,您可以使用ssl_optsSSL_ca_file设置自己的信任存储区,其中包含缺少的CA证书。

答案 1 :(得分:4)

适用于我的IO ::套接字:: SSL 2.052,WWW :: Mechanize 1.86和Net :: SSLeay 1.80。我怀疑你需要升级Net :: SSLeay。我建议升级所有这些。

差异从这里开始。你认为证书不合适。

DEBUG: .../IO/Socket/SSL.pm:2552: did not get stapled OCSP response
DEBUG: .../IO/Socket/SSL.pm:2505: ok=0 cert=102327360

但我的确如此。更详细的输出是因为我升级了Net :: SSLeay。

DEBUG: .../IO/Socket/SSL.pm:2722: did not get stapled OCSP response
DEBUG: .../IO/Socket/SSL.pm:2675: ok=1 [2] /C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2009 Entrust, Inc. - for authorized use only/CN=Entrust Root Certification Authority - G2/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2009 Entrust, Inc. - for authorized use only/CN=Entrust Root Certification Authority - G2

该过程由Net :: SSLeay处理。您的Net :: SSLeay版本可能与您的OpenSSL C库不兼容。自从ActivePerl 5.20.2问世以来,已经有a lot of fixes for compatibility with OpenSSL 1.1