You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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格式公钥,解决方法有两种:

  1. 手动转换公钥格式
    用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('远程文件路径', '本地保存路径');
  1. 用模块自动解析
    安装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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:45:41