根据您安装的SSL模块不同,有两种方法可以实现此操作。LWP文档建议安装Crypt :: SSLeay。如果您已经这样做了,则将 HTTPS_CA_FILE
环境变量设置为指向您的ca-bundle.crt即可解决问题。( Crypt :: SSLeay文档提到了这一点,但细节比较少)。此外,根据您的设置,您可能需要设置 HTTPS_CA_DIR
环境变量。
Crypt :: SSLeay示例:
使用 LWP::Simple qw(get) 模块下载网页内容;
$ENV{HTTPS_CA_FILE} = "/path/to/your/ca/file/ca-bundle";
$ENV{HTTPS_DEBUG} = 1;
print get("https://some-server-with-bad-certificate.com");
__END__
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:unknown CA
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:bad certificate
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:error in SSLv2 read server hello B
请注意,get函数不会抛出异常,但会返回undef。
或者,您可以使用IO::Socket::SSL模块(也可从CPAN获取)。要验证服务器证书,需要修改SSL上下文默认值:
使用 IO::Socket::SSL qw(debug3);
使用 Net::SSLeay;
BEGIN {
IO::Socket::SSL::set_ctx_defaults(
verify_mode => Net::SSLeay->VERIFY_PEER(),
ca_file => "/path/to/ca-bundle.crt",
# ca_path => "/alternate/path/to/cert/authority/directory"
);
}
使用 LWP::Simple qw(get);
警告:get("https:://some-server-with-bad-certificate.com")将返回undef,但会在执行时打印到STDERR(以及如果从IO::Socket::SSL导入debug*符号,则会打印一堆调试信息):
此版本还会导致get()
在执行时返回undef,但会将警告打印到STDERR
(以及如果您从IO::Socket::SSL中导入debug*符号,则会打印大量调试信息):
% perl ssl_test.pl
DEBUG: .../IO/Socket/SSL.pm:1387: 新的 ctx 139403496
DEBUG: .../IO/Socket/SSL.pm:269: 套接字尚未连接
DEBUG: .../IO/Socket/SSL.pm:271: 套接字已连接
DEBUG: .../IO/Socket/SSL.pm:284: SSL 握手未开始
DEBUG: .../IO/Socket/SSL.pm:327: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1135: SSL 连接尝试失败,原因为未知错误error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:333: 致命的 SSL 错误:SSL 连接尝试失败,原因为未知错误error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:1422: 释放 ctx 139403496 open=139403496
DEBUG: .../IO/Socket/SSL.pm:1425: OK 释放 ctx 139403496
DEBUG: .../IO/Socket/SSL.pm:1135: IO::Socket::INET 配置失败error:00000000:lib(0):func(0):reason(0)
500 无法连接到 some-server-with-bad-certificate.com:443 (SSL 连接尝试失败,原因为未知错误error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed)