问题描述
我正在尝试使用以下 perl 脚本访问 xenapi。 “http”版本似乎有效,但“https”版本无效。 代码:
#!/usr/bin/perl
use 5.20.0;
use RPC::XML::Client;
use Data::Dumper;
use IO::Socket::SSL qw( SSL_VERIFY_NONE );
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
$ENV{HTTPS_DEBUG} = 1;
$Data::Dumper::Indent = 1;
$Data::Dumper::Sortkeys = 1;
use Xen::API;
my $user='Gordon';
my $passwd='Freeman';
my $xen = RPC::XML::Client->new("https://xen1.blackmesa.gov",ssl_opts => {
verify_hostname => 0,SSL_verify_mode => SSL_VERIFY_NONE
},);
my $test = $xen->simple_request('session.login_with_password',$user,$passwd);
say '$RPC::XML::ERROR = '.Dumper($RPC::XML::ERROR);
say '$xen = '.Dumper($xen);
这里是脚本的输出:
$RPC::XML::ERROR = $VAR1 = 'RPC::XML::Client::simple_request: RPC::XML::Client::send_request: HTTP server error: Can\'t connect to xen1.blackmesa.gov:443 (certificate verify Failed)';
$xen = $VAR1 = bless( {
'__compress' => 'deflate','__compress_re' => qr/deflate/,'__compress_requests' => 0,'__compress_thresh' => 4096,'__message_file_thresh' => 1048576,'__message_temp_dir' => '','__parser' => bless( [
[]
],'RPC::XML::Parser::XMLParser' ),'__request' => bless( {
'_content' => '','_headers' => bless( {
'accept-encoding' => 'deflate','content-type' => 'text/xml'
},'HTTP::Headers' ),'_method' => 'POST','_protocol' => 'HTTP/1.1','_uri' => bless( do{\(my $o = 'https://xen1.blackmesa.gov')},'URI::https' )
},'HTTP::Request' ),'__request_as_string' => undef,'__useragent' => bless( {
'def_headers' => bless( {
'user-agent' => 'RPC::XML::Client/1.44 libwww-perl/6.52'
},'handlers' => {
'response_header' => bless( [
{
'callback' => sub { "DUMMY" },'line' => '/usr/share/perl5/LWP/UserAgent.pm:768','m_media_type' => 'html','owner' => 'LWP::UserAgent::parse_head'
}
],'HTTP::Config' )
},'local_address' => undef,'max_redirect' => 7,'max_size' => undef,'no_proxy' => [],'protocols_allowed' => undef,'protocols_forbidden' => undef,'proxy' => {},'requests_redirectable' => [
'GET','HEAD'
],'send_te' => 1,'show_progress' => undef,'ssl_opts' => {
'verify_hostname' => '0'
},'timeout' => 180,'use_eval' => 1
},'LWP::UserAgent' ),'ssl_opts' => {
'SSL_verify_mode' => 0,'verify_hostname' => 0
}
},'RPC::XML::Client' );
任何提示如何使代码工作?
可疑的是 ssl_opts 实际上是 $xen
转储的 2 倍。
以下 python 脚本似乎有效,所以我假设 Xenapi over https 有效。
import XenAPI
session = XenAPI.Session('https://xen1.blackmesa.gov:443',ignore_ssl=True)
session.xenapi.login_with_password('Gordon','Freeman',"2.3","test")
hosts = session.xenapi.host.get_all()
for host in hosts:
vms = session.xenapi.host.get_resident_VMs(host)
print (vms)
在 python 脚本中没有 ignore_ssl=True
我得到以下错误:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_Failed] certificate verify Failed: EE certificate key too weak (_ssl.c:1123)
这是openssl s_client -showcerts -connect xen1.blackmesa.gov
的相关输出
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH,P-384,384 bits
---
SSL handshake has read 1134 bytes and written 532 bytes
Verification error: self signed certificate
---
New,TLSv1.2,Cipher is ECDHE-RSA-AES256-SHA384
解决方法
我已经设法通过以下方式解决了这个问题:
- 从服务器获取证书并将其保存到文件中:
openssl s_client -showcerts -connect <server>:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem
-
将
HTTPS_CA_FILE
或PERL_LWP_SSL_CA_FILE
环境变量设置为 mycertfile.pem 位置,这两个变量都在 LWP 文档中进行了描述。 -
由于在我的情况下服务器使用的是弱密钥,我必须将
SECLEVEL
中的/etc/ssl/openssl.conf
设置为 1:CipherString = DEFAULT@SECLEVEL=1
最终代码如下:
use RPC::XML::Client;
use Xen::API;
$ENV{HTTPS_CA_FILE} = '<location_of_mycertfile.pem>';
my $xen = RPC::XML::Client->new("https://xen1.blackmesa.gov")
my $test = $xen->simple_request('session.login_with_password',"user","passwd");
print $test->{'Status'} if $test;