如何在密钥不匹配时判断phpseclib sftp响应是否是密码请求的挑战

时间:2017-09-27 18:42:53

标签: php sftp phpseclib

最近有人无意中将用于我的ssh / sftp的密钥文件更改为远程服务器。当我尝试从命令行ssh到服务器时,我推断出这一点,并且我遇到了密码请求,这表明该密钥已不再被识别。

如何让我的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是一个空数组。

1 个答案:

答案 0 :(得分:1)

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不知道身份验证 - 这完全由SSH层处理。即。它不是你想看的SFTP错误,而是SSH错误。

参考代码:https://github.com/phpseclib/phpseclib/blob/1.0.7/phpseclib/Net/SSH2.php#L2219

其他可能的密码请求机制

密码请求可能不是来自SSH的内置身份验证机制。您可能从“publickey”SSH_MSG_USERAUTH_REQUEST获得SSH_MSG_USERAUTH_SUCCESS响应。

此时我可以看到两种可能性:

  1. 这可能是您看到的横幅消息。您可以通过$sftp->getBannerMessage()

  2. 来获取这些内容
  3. 当您进入服务器而不是SFTP进入服务器时,您可能只会看到此错误。即。除非您执行$ssh->exec()$ssh->write(),否则您可能看不到错误。此时,“错误”可以通过stderr或stdout传达给您。

  4. 要确定我必须看到SSH日志。 phpseclib日志可能足够,也可能不足。我的意思是你可以$sftp->exec('pwd');$sftp->read('[prompt]');,但我的猜测是你还没有这样做。如果您想要走这条路线,可以执行define('NET_SSH2_LOGGING', 2);,然后执行echo $sftp->getLog()$sftp->exec()之后$sftp->read()

    PuTTY日志可能更有用。要获取它们,您可以转到PuTTY-> Session-> Logging,检查“SSH数据包”单选按钮,然后照常连接。

    不幸的是,据我所知,OpenSSH没有记录原始/解密的SSH2数据包,所以OpenSSH在这里不会太有用。

相关问题