我想访问一个无法验证证书的网站(主机名不正确,并且我无法在应用程序指向的服务器上更改/更新证书)。我正在使用Mojo::UserAgent
来获取请求。那么如何忽略它并继续连接到该网站呢?
我已经看到没有选择。
我不想使用LWP::UserAgent
。
我已经使用WWW::Curl
和WWW::Curl::Easy
完成了此操作,但是我想使用Mojo::UserAgent
清除代码(在整个应用程序中都使用过)。
最佳答案
主机名不正确...那么该如何忽略它并继续连接到该网站?
仅由于主机名与证书不匹配而放弃任何形式的验证是一个非常糟糕的主意。为什么要完全使用TLS?
更好的方法是预先了解您期望的证书,并验证您确实获得了该证书。使用选项SSL_fingerprint
可以轻松完成此操作。不幸的是,Mojo :: UserAgent没有提供设置连接特定参数的方法,因此您需要在连接之前立即进行设置,然后再进行其他连接:
use IO::Socket::SSL 1.980;
IO::Socket::SSL::set_client_defaults(
SSL_fingerprint => "sha256$55a5dfaaf..."
);
... use Mojo::UserAgent to connect ..
IO::Socket::SSL::set_client_defaults(); # set back
有关使用此选项以及如何获取指纹的更多信息,请参见Certificate error in Perl。
如果仅主机名不正确的另一种方法是使用
SSL_verifycn_name
选项指定证书中期望的主机名。IO::Socket::SSL::set_client_defaults(
SSL_verifycn_name => 'foo.example.com',
);
set_args_filter_hack
函数可以完成另一种方法,该函数旨在处理设置了奇怪默认值或不允许用户设置自己的值的模块:my $hostname = undef;
IO::Socket::SSL::set_args_filter_hack(
sub {
my ($is_server,$args) = @_;
$args->{SSL_verifycn_name} = $hostname if $hostname;
}
);
...
$hostname = 'foo.example.com';
... do something with Mojo::UserAgent ...
$hostname = undef;
这样,您可以调整每个SSL握手的设置。
有关更多信息,请参见documentation of IO::Socket::SSL,尤其是有关常见用法错误的部分。这部分还记录了您应该怎么做,而不是在证书的某些部分错误时禁用任何形式的验证。
'SSL connect attempt failed error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol'
curl ... SSL connection using TLS_RSA_WITH_RC4_128_MD5
我的猜测是您在此处面临的问题与证书验证无关。鉴于该服务器使用的密码非常老旧,即RC4-MD5,我将假定该服务器只能处理SSL 3.0。由于安全原因,一段时间以来,此版本已被禁用:IO :: Socket :: SSL。暂时明确使用此不安全版本:
IO::Socket::SSL::set_client_defaults(
SSL_version => 'SSLv3'
);