最近有人无意中将我的 ssh/sftp 使用的 key 文件更改为远程服务器。当我尝试从命令行 ssh 到服务器并收到密码请求时,我推断出这一点,这表明 key 不再被识别。
如何让我的 php 程序检测到意外的密码挑战?目前我有这个:
$sftp = new SFTP(self::DOMAIN_NAME);
$Key = new RSA();
$private_rsa_key = file_get_contents('/home/ddfs/.ssh/' . self::KEY_FILE);
$Key->loadKey($private_rsa_key);
$rc = $sftp->login(self::USER, $Key);
$errors = $sftp->getSFTPErrors();
目前我看到 $rc 设置为 FALSE 并且 $errors 是一个空数组。
最佳答案
SSH 发起的密码更改请求
SSH 有一个内置的密码重置机制。我的阅读RFC4252 § 8意味着 SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 数据包只能作为对“密码”SSH_MSG_USERAUTH_REQUEST 的响应而发送,但谁知道 OpenSSH 开发人员如何解释 RFC 的该部分。
由于您正在进行公钥身份验证,phpseclib 将发送“公钥”SSH_MSG_USERAUTH_REQUEST,因此 SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 似乎不是有效的响应,但谁知道呢。
如果服务器确实使用 SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 数据包进行响应,那么您可以这样做 $sftp->getErrors()
(而不是 getSFTPErrors
)并查找以 SSH_MSG_USERAUTH_PASSWD_CHANGEREQ:
开头的一个。也许甚至可以$sftp->getLastError()
.
getSFTPErrors
返回 SFTP 层的错误 - 而不是 SSH2 层。 SFTP 作为一种协议(protocol)不知道身份验证 - 这完全由 SSH 层处理。 IE。您想要查看的不是 SFTP 错误,而是 SSH 错误。
引用代码:https://github.com/phpseclib/phpseclib/blob/1.0.7/phpseclib/Net/SSH2.php#L2219
其他可能的密码请求机制
密码请求可能不是来自 SSH 的内置身份验证机制。您可能会从“公钥”SSH_MSG_USERAUTH_REQUEST 获得 SSH_MSG_USERAUTH_SUCCESS 响应。
此时我可以看到两种可能性:
您看到的可能是一条横幅消息。您可以通过
$sftp->getBannerMessage()
获得这些.您可能仅在通过 SSH 访问服务器而不是通过 SFTP 访问服务器时看到此错误。 IE。除非您这样做,否则您可能不会看到该错误
$ssh->exec()
或$ssh->write()
。此时,“错误”可以通过 stderr 或 stdout 传达给您。
要确定,我必须查看 SSH 日志。 phpseclib 日志可能足够,也可能不够。我的意思是你可以这样做$sftp->exec('pwd');
或$sftp->read('[prompt]');
但我的猜测是你还没有这样做。如果你想走那条路,你可以这样做 define('NET_SSH2_LOGGING', 2);
然后echo $sftp->getLog()
在执行 $sftp->exec()
之后或$sftp->read()
.
PuTTY 日志可能更有用。要获取它们,您可以转到 PuTTY-> session ->日志记录,选中“SSH 数据包”单选按钮,然后照常连接。
不幸的是,据我所知,OpenSSH 不会记录原始/解密的 SSH2 数据包,因此 OpenSSH 在这里不会太有用。
关于php - 当 key 不匹配时,如何判断 phpseclib sftp 响应是否是密码请求的质询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46455067/