我正在尝试使用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成功检索网页。
答案 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不被视为可信任,因此验证将失败。
有几种可能的修复方法。
SSL_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。