最近有人无意中将用于我的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是一个空数组。
答案 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响应。
此时我可以看到两种可能性:
这可能是您看到的横幅消息。您可以通过$sftp->getBannerMessage()
。
当您进入服务器而不是SFTP进入服务器时,您可能只会看到此错误。即。除非您执行$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-> Logging,检查“SSH数据包”单选按钮,然后照常连接。
不幸的是,据我所知,OpenSSH没有记录原始/解密的SSH2数据包,所以OpenSSH在这里不会太有用。