我创建了一个脚本,该脚本使用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"
只是简单地添加到require
JSON 的 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
以前相同的内容)。帮助..?