-2

我创建了一个脚本,该脚本使用phpseclib扩展名连接到服务器,使用公钥认证(如您在此处看到的),通过使用ssh-keygen.

我现在面临的是,当我从本地主机运行 php 脚本时,连接工作得很好,但是当我从服务器运行脚本时,我总是尝试登录失败,并报告以下错误:

SSH_MSG_USERAUTH_FAILURE

(我$sftp->getLastError()在尝试后使用时得到$sftp->login())。

知道为什么会这样吗????

更新

认为这可能是由于与 file_get_contents() 相关的一些错误,所以我检查了它,它确实是键的值。我也直接将私钥粘贴到 PublicKeyLoader::load() 函数中,发生了同样的错误,所以这不是原因。

我认为发生问题的主要日志事件是,当运行完全相同的脚本试图建立与目标服务器的连接时:

从本地主机(工作):

NET_SSH2_MSG_SERVICE_REQUEST;
NET_SSH2_MSG_SERVICE_ACCEPT;
NET_SSH2_MSG_USERAUTH_REQUEST (ssh-connection none); 
NET_SSH2_MSG_USERAUTH_FAILURE; 
NET_SSH2_MSG_USERAUTH_REQUEST(ssh-connection publickey); 
NET_SSH2_MSG_USERAUTH_PK_OK;

从服务器(不工作):

NET_SSH2_MSG_SERVICE_REQUEST;
NET_SSH2_MSG_SERVICE_ACCEPT;
NET_SSH2_MSG_USERAUTH_REQUEST (ssh-connection none); 
NET_SSH2_MSG_USERAUTH_FAILURE;
NET_SSH2_MSG_USERAUTH_REQUEST (ssh-connection publickey); 
NET_SSH2_MSG_USERAUTH_FAILURE;

我生成了三个密钥对,使用它们运行了 localhost 和服务器-客户端测试,我总是得到上面显示的内容。当我回显它时,我肯定得到了密钥,不用担心它不是加密的 OpenSSH 私钥,这不是原因(不支持phpseclib),然后在 localhost 上也会失败(我已经测试)。

所以看起来它在服务器上的公钥认证步骤上失败了,尽管我使用的是完全相同的脚本,虽然我在回显检索到的密钥时得到了完全正确的密钥,但也在服务器端.

然后,我检查了如果我更改密钥的单个字符会发生什么;如果这重现了上面显示的 SSH - 日志,但没有。如果我这样做,脚本会在记录任何内容之前中断,抛出phpseclib3\Exception\NoKeyLoadedException: Unable to read key异常。

由此我得出结论,唯一的问题可能是密钥在发送到服务器之前以某种错误的方式编码,并且服务器因此误解了密钥。

考虑到这一点,我发现phpseclib需要paragonie根据this的包,以及做一些 base64 编码的phpseclibs依赖项之一。paragonie因此,我认为用于发送密钥的编码可能由于某种原因未正确完成,并检查了phpseclib扩展程序是如何安装在服务器上的(由服务器管理员完成,而不是由我完成)。

原来它是一个 plesk 服务器,它要求你以一种有点不寻常的方式上传新的作曲家包,即通过composer.json文件,根据这个。我只通过命令提示符、直接在服务器上通过 SSH 或在服务器上部署的本地环境安装了 composer 包。这两项工作都没有,上面的说明也不起作用。

然后我检查了composer.json文件,发现它的内容是:

{ 
  "name": "packagex/packagex", 
  "type": "plugin", 
  "description": "secret_description", 
  "keywords": ["secret_keyword"], 
  "homepage": "secret_url", 
  "license": "secret_license", 
  "authors": [ { "name": "secret_name", "email": "secret_mail" } ],
  "require": 
    {
      "php": ">=5.3", 
      "phpseclib/phpseclib": "^3.0"
    }
}

该文件已经包含一个扩展名,我们无法触摸,但我们需要添加phpseclib. 为此,该行"phpseclib/phpseclib": "^3.0"只是简单地添加到requireJSON 的 key 中,但我觉得这不是正确的方法。恕我直言,这种解释phpseclib为已使用包的依赖项,它们彼此完全独立。

我现在开始认为,这可能是脚本在服务器端运行时失败的最后一个原因:就其依赖项而言,包没有正确安装,因此依赖项phpseclib本身需要没有正确使用,因为phpseclib包本身被列为依赖项。因此,某些缺少 base64 编码或类似的(包paragonie的依赖项phpseclib,见上文)可能会导致问题。这可能吗?消除这个原因;我需要知道如何composer.json在 plesk 服务器上通过 composer via 正确安装扩展,而无需触及以前以这种方式安装的包。关于如何做到这一点的任何想法?我还为此发布了一个单独的问题,以获取更多详细信息;你可以检查一下

也可能导致问题的是当前composer.json文件需要一个低于 atm 所需的 php 版本phpseclib(php:> = 5.6.1)。但同样,要改变这一点,我需要知道如何以composer.json正确的方式修改文件。

更新

我已经composer.json通过将其内容从 plesk 服务器复制到我下载作曲家的本地环境来更新文件。然后我通过命令提示符安装phpseclib包,然后将结果复制composer.json回 Plesk 服务器。而且我再次遇到完全相同的问题(除了与composer.json以前相同的内容)。帮助..?

4

1 回答 1

2

所以发生的事情是我已经检查了目标服务器上的(在被阻止的 IP 等中)它在哪个端口上侦听 SFTP 连接。我注意到它 A) 没有在标准端口上侦听 B) 阻止了标准端口上的传入连接请求。

奇怪的是,当从本地机器运行时,可以毫无问题地建立 SSH 连接,无需指定任何端口,因此始终使用标准端口。

在服务器上部署的脚本中,如果连接请求是在服务器配置为侦听 SFTP 的端口上发出的,则可以独占建立 SSH 连接。

更有趣的是,当我在其中指定非标准端口时,在 localhost 上运行的脚本以部署脚本失败的方式失败。

所以最后,不知道为什么会发生这种情况,但肯定都是通过测试证实的。

于 2021-11-11T21:36:15.037 回答