使用Perl Net::SSH2连接服务器时如何更改主机密钥算法类型?
解决Net::SSH2连接时主机密钥算法适配问题(ssh-ed25519/rsa-sha2系列)
一、直接在Net::SSH2中指定主机密钥算法
你当前用的Net::SSH2底层依赖libssh2库,首先得确保libssh2版本在1.7.0以上(旧版本不支持rsa-sha2系列主机密钥)。可以用这条命令查版本:
pkg-config --modversion libssh2
版本达标后,在代码里通过method方法指定允许的主机密钥算法列表,优先级按你写的顺序来:
use Net::SSH2; my $ssh = Net::SSH2->new(); # 强制指定仅使用客户允许的主机密钥算法 $ssh->method('hostkey', 'ssh-ed25519,rsa-sha2-512,rsa-sha2-256'); # 发起连接 $ssh->connect('客户服务器地址') or die $ssh->error; # 处理主机密钥验证:如果之前known_hosts里存的是旧的ssh-rsa密钥,先删掉对应条目 # 首次连接可以获取新密钥并保存到known_hosts my ($new_key_type, $new_key_data) = $ssh->remote_hostkey; print "服务器新主机密钥类型:$new_key_type\n"; # 手动保存格式参考:服务器地址,IP 密钥类型 base64编码密钥 # 继续用你的ssh-rsa公私钥做用户认证(注意:用户公私钥和主机密钥是两回事,只要客户服务器允许ssh-rsa认证就不用换) $ssh->auth_publickey('你的用户名', '本地公钥路径', '本地私钥路径') or die $ssh->error; # 后续下载文件逻辑 my $sftp = $ssh->sftp(); $sftp->get('远程文件路径', '本地保存路径') or die $sftp->error;
二、解决Net::SSH::Perl的OpenSSH格式公钥问题(备选方案)
你提到Net::SSH::Perl不接受OpenSSH格式公钥,解决方法有两种:
- 手动转换公钥格式
用ssh-keygen把OpenSSH格式转成RFC4716格式:
ssh-keygen -e -f 你的公钥文件路径 -m RFC4716 > 转换后的公钥文件路径
然后在代码里用转换后的公钥:
use Net::SSH::Perl; my $ssh = Net::SSH::Perl->new('客户服务器地址', host_key_alg => ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256']); $ssh->login('你的用户名', undef, undef, '本地私钥路径', '转换后的公钥路径'); # SFTP下载逻辑 my $sftp = $ssh->sftp(); $sftp->get('远程文件路径', '本地保存路径');
- 用模块自动解析
安装Convert::SSH2模块,直接解析OpenSSH格式公钥,不用手动转换:
use Net::SSH::Perl; use Convert::SSH2; # 读取OpenSSH格式公钥 my $pub_key = do { local $/; open my $fh, '<', '你的公钥文件路径'; <$fh> }; # 转换为Net::SSH::Perl支持的格式 my $converted_pub = Convert::SSH2::pubkey_to_ssh2($pub_key); # 写入临时文件供Net::SSH::Perl使用 open my $tmp_fh, '>', '/tmp/converted_pub.key' or die $!; print $tmp_fh $converted_pub; close $tmp_fh; # 后续连接逻辑 my $ssh = Net::SSH::Perl->new('客户服务器地址', host_key_alg => ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256']); $ssh->login('你的用户名', undef, undef, '本地私钥路径', '/tmp/converted_pub.key');
三、额外推荐:用Net::OpenSSH简化适配
如果上面两种模块都有兼容问题,试试Net::OpenSSH——它直接调用系统的OpenSSH客户端,支持所有OpenSSH原生支持的算法,兼容性拉满:
use Net::OpenSSH; my $ssh = Net::OpenSSH->new('客户服务器地址', user => '你的用户名', key_path => '本地私钥路径', hostkey => ['ssh-ed25519', 'rsa-sha2-512', 'rsa-sha2-256']); $ssh->error and die "连接失败:" . $ssh->error; # SCP下载文件 $ssh->scp_get('远程文件路径', '本地保存路径') or die $ssh->error;
内容的提问来源于stack exchange,提问作者theevilking
相关产品推荐
相关产品推荐

