phpseclib 密钥登录失败如何解决?

Dar*_*ook 1 phpseclib

我一直在尝试 phpseclib,以运行一个简单的 SSH 会话到各种云服务器。每次使用一键登录。

使用没有密码保护的密钥进行测试是可以的:我在标准端口 22 上尝试了一个,然后在非标准端口上尝试了另一个,两者都有效。(两者都在不同地区的 Amazon EC2 上。)

但是我尝试的第一个测试失败了,原因是:

SSH_MSG_USERAUTH_FAILURE: publickey,password
Run Code Online (Sandbox Code Playgroud)

它有一个受密码保护的密钥,带有一个非标准端口。这是我的脚本(已更改名称以保护无辜者):

include('Net/SSH2.php');
include('Crypt/RSA.php');

$ssh = new Net_SSH2('10.1.2.3', /*port*/999);
$key = new Crypt_RSA();

$key->setPassword('secrets');
$ret = $key->loadKey(file_get_contents('/home/tester/.ssh/my_private_key'));
if(!$ret){
    echo "loadKey failed\n";
    exit;
    }

if (!$ssh->login('ubuntu', $key)) {
    print_r($ssh->errors);
    exit("Login Failed\n");
    }

echo $ssh->exec('pwd');
echo $ssh->exec('ls -la');
Run Code Online (Sandbox Code Playgroud)

我做了ssh-agent -d /home/tester/.ssh/my_private_key(强迫它提示我),然后在命令行上使用 ssh,它工作了。如果我跳过设置密码,则loadKey()返回 false。

所以,现在我想知道是否不支持密钥类型?“坏”键是这样开始的:

-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A541E5B6B9077483BCEF845

YMMV4.....
Run Code Online (Sandbox Code Playgroud)

而“好”键以:

-----BEGIN RSA PRIVATE KEY-----
YMMVgIBab54...
Run Code Online (Sandbox Code Playgroud)

我发现了这个问题,其中 Proc-Type 和 DEK-Info 看起来不错,但他是 RSA,而不是 DSA。那么 DSA 是问题所在吗?(但如果是这样,当我尝试这样做时 phpseclib 不应该抱怨loadKey()吗?)

关于如何获得有关该问题的更多信息的任何建议?(不在这里发布实际的密钥!)

Dar*_*ook 5

要回答我的问题的“如何排除故障”部分,您可以define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX);在创建Net_SSH2对象之前添加。然后就在退出 do file_put_contents("ssh.log",$ssh->getLog());(或echo $ssh->getLog())之前。这会记录发送到远程服务器的每个字节以及接收到的每个字节。(完整的修改脚本如下。)

不幸的是,当仅支持 RSA 时,您必须是领域专家才能使用它来识别使用 DSA 密钥的问题。但是,对于其他问题,这种故障排除方法可能正是您所需要的。

include('Net/SSH2.php');
include('Crypt/RSA.php');

define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX);
$ssh = new Net_SSH2('10.1.2.3', /*port*/999);
$key = new Crypt_RSA();

$key->setPassword('secrets');
$ret = $key->loadKey(file_get_contents('/home/tester/.ssh/my_private_key'));
if(!$ret){
    echo "loadKey failed\n";
    file_put_contents("ssh.log",$ssh->getLog());
    exit;
    }

if (!$ssh->login('ubuntu', $key)) {
    print_r($ssh->errors);
    file_put_contents("ssh.log",$ssh->getLog());
    exit("Login Failed\n");
    }

echo $ssh->exec('pwd');
echo $ssh->exec('ls -la');
file_put_contents("ssh.log",$ssh->getLog());
Run Code Online (Sandbox Code Playgroud)