在 phpseclib 中使用 RSA 密钥登录失败(超时)

Login with RSA key in phpseclib fails (times out)

我正在使用 phpseclib 并尝试使用 RSA 密钥登录:

$ssh = new SSH2('<server_domain_name>');
$key = new RSA();
$key->load(file_get_contents('<private_key_path>'));
if($ssh->login('root',$key)){
    echo "Logged In!!!";
} else {
    echo "Login failed!";
}

但是登录失败!查看 SSH2 class 内部,我可以看到使用 RSA 密钥登录发生在 _login_helper() 函数中(如果我错了,请更正),该函数由 _login() 函数调用login() 函数(在某些情况下)。

login() -> _login() -> _login_helper()

但是这段代码:

if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
    if (!$this->_connect()) {
        return false;
    }
}

在 _login() 函数中总是 returns false,因此执行永远不会到达 _login_helper() 函数。上面部分代码返回false的原因是这些variables/constants:

的默认值
var $bitmap = 0;
const MASK_CONNECTED     = 0x00000002;

我有点沮丧。我错过了什么吗?

编辑: 几秒钟后我忘了提及登录 returns/fails。在 _connect() 方法中添加一些 ECHO,我可以看到该方法在等待服务器数据时超时。在这个循环的执行过程中:

while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches))

服务器只输出一行 "SSH-2.0-OpenSSH_4.3" 然后(第二次循环执行)它在这里超时:

if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {

编辑 2: 我尝试连接的一方的 SSH 日志说:

THE_SSH_SERVER_IP
关闭了连接 11 月 4 日 23:09:58 web1 sshd[10316]:未收到来自 THE_ WEB_SERVER_IP

的标识字符串

phpseclib 在发送它自己的之前读取服务器的服务器标识字符串。这就是 PuTTY 所做的。作为证据,这是我尝试连接到 localhost:4022:

时来自 PuTTY 的示例日志文件
Event Log: Writing new session log (SSH packets mode) to file: putty.log
Event Log: Looking up host "127.0.0.1"
Event Log: Connecting to 127.0.0.1 port 4022
Event Log: Server version: SSH-2.0-OpenSSH_6.6p1 Ubuntu-2ubuntu1
Event Log: Using SSH protocol version 2
Event Log: We claim version: SSH-2.0-PuTTY_Release_0.63

以下是 SSH 规范的内容:

   When the connection has been established, both sides MUST send an
   identification string.  This identification string MUST be

      SSH-protoversion-softwareversion SP comments CR LF

来源:https://www.rfc-editor.org/rfc/rfc4253#section-4.2

请注意,这并不是说一方必须在另一方之前发送。双方都应该拥有可立即检索的内容。如果您的 SSH 服务器仅在客户端发送其标识字符串后才有条件地使内容可供检索,那么您的 SSH 服务器有问题。让我知道您使用的是什么服务器,我会打开一个关于它的错误报告。

同时,这里是 phpseclib 的修改版本,它先发送标识字符串而不是先读取它:

https://github.com/terrafrost/phpseclib/tree/send-identifier-first

让我知道这是否适合您。并让我知道您使用什么作为服务器。