我有很多脚本,其中大部分基于WWW::Mechanize
从可通过 HTTPs 访问的杂项硬件中刮取数据。在升级了我的大部分 perl 安装及其模块后,所有使用 HTTPS:// 的脚本都因以下原因而中断"certificate verify failed"
这是因为较新版本的 LWP 对证书进行了适当的检查,以及 dies
是否存在不匹配的情况。
就我而言,由于这种情况,预计证书身份验证会失败,因此我需要找到一种彻底规避此检查的方法。
我有很多脚本,其中大部分基于WWW::Mechanize
从可通过 HTTPs 访问的杂项硬件中刮取数据。在升级了我的大部分 perl 安装及其模块后,所有使用 HTTPS:// 的脚本都因以下原因而中断"certificate verify failed"
这是因为较新版本的 LWP 对证书进行了适当的检查,以及 dies
是否存在不匹配的情况。
就我而言,由于这种情况,预计证书身份验证会失败,因此我需要找到一种彻底规避此检查的方法。
假设我想告诉你一些事情,我不想让其他人知道。我们会安排一个密码,我会用它来加密消息,然后我会将消息发送给你。
如果我不能确定向我提供密码和加密信息的人是你怎么办?那么任何数量的人都可以简单地冒充您,而加密将是徒劳的。直到最近,这还是 LWP 的 HTTPS 支持状态。
现在,LWP 实际上会检查它正在与谁交谈,除非您要求 LWP 像以前那样行事。你可以这样做:
my $ua = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 },
);
如果您想影响脚本中的所有 LWP::UserAgent 实例而不在所有地方指定选项,您可以将以下内容添加到您的脚本中
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
或者您可以按如下方式启动您的脚本:
PERL_LWP_SSL_VERIFY_HOSTNAME=0 script.pl
最后,如果您希望 LWP 始终不安全,您可以将以下内容添加到您的登录脚本中:
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
但是,我不推荐以上任何一种。更好的选择是为您正在与之通信的主机提供证书。(这相当于在 Firefox中添加异常,如果你明白我的意思的话。)请参阅$ua->ssl_opts
.
对我来说,使用:
my $ua = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 },
);
产量
不推荐对客户端使用 SSL_VERIFY_NONE 的 SSL_verify_mode 的默认值!请将 SSL_verify_mode 设置为 SSL_VERIFY_PEER 以及 SSL_ca_file|SSL_ca_path 以进行验证。如果您真的不想验证证书并保持连接对中间人攻击开放,请在您的应用程序中将 SSL_verify_mode 显式设置为 SSL_VERIFY_NONE。
使用它没有给出任何警告:
my $ua = LWP::UserAgent->new(
ssl_opts => { SSL_verify_mode => 'SSL_VERIFY_NONE'},
);
我在我的代码前面加上:
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
这导致脚本以干净简单的方式绕过检查。
@ikegami 为您为什么不想禁用 SSL 主机名验证提供了一个很好的论据,但没有直接提及如何避免它。
如果您使用 CA 签名证书与公共系统通信,则需要将 LWP 指向您的发行版的根证书集合。在基于 Debian 的系统(Ubuntu 等)下,它保存在/etc/ssl/certs/
.
BEGIN {
$ENV{HTTPS_CA_DIR} = '/etc/ssl/certs'
}
如果您使用自签名证书与自己的服务器通信,则可以在客户端上保存该证书的副本,并将脚本指向该特定文件。
BEGIN {
$ENV{HTTPS_CA_FILE} = '/path/to/my/server-certificate.crt'
}
您可以在运行脚本之前在环境中设置这些(例如,从您的 shell 中导出它们),或者您可以将设置直接应用到您的 UserAgent 对象。有关详细信息,请参阅LWP::UserAgent 文档;搜索ssl_opts
(大约在页面的中间)。