3

我正在使用phpseclib,需要创建几个 php 函数,使某人能够以编程方式 ssh 进入他们的服务器并更改 root 密码,还更改可能忘记密码的用户的密码(因此必须以根)。

我尝试使用 libssh2,但发现使用起来有点讨厌。我现在正在研究 phpseclib,它看起来更健壮。但是当我尝试像这样使用“su”命令时:

echo $ssh->exec('su');

我得到答复:

su: must be run from a terminal

当我尝试使用 sudo 时:

echo $ssh->exec('sudo passwd root');

我得到错误:

sudo: no tty present and no askpass program specified

无论如何,事实证明 su 对于直接 ssh 访问是禁用的,但是在查看了这篇文章之后,事实证明你可以使用以下命令来做到这一点:

ssh -t -t -l 'username' 'host' 'su -'

从我的笔记本电脑(运行 ubuntu)进入终端时,这最终对我有用,然后我输入了我的密码,然后输入了 root 密码来完成。

引用上面链接的网站:

当给出 -t 时,SSH 命令(使用 -t)远程 sshd 以建立到工作进程的“伪终端”管道。

. 只要它的标准输入是终端,ssh 就会这样做。

. 但是如果 ssh 的标准输入是非终端,
除非给出两个 -t,否则 ssh 不会指示 sshd 建立伪终端:

回显密码 | ssh -t -t -l 用户名 remote_host

. 因此,使用 -t -t(来自 ssh)sshd 为客户端进程设置了一个伪终端。

. 客户端,无论是 'tty' 还是 'su' 都无法判断它已连接到虚构的 > 终端:

回声dummystr | ssh -t -t -l 用户名 host.com -c ''tty'

回显密码 | ssh -t -t -l 用户名 host.com -c 'su -'

于是就有了答案。如果您通过一个 >interactive 客户端 ssh(如 OpenBSD 中的客户端 ssh)在 linux 机器上“su root”,请使用 double -t。

因此,正如我上面所说,它实际上是在终端上工作的:

ssh -t -t -l 'username' 'host' 'su -'

但我真的希望能够使用 phpseclib 执行此命令。唯一的问题是我不知道如何将任何标志放入 exec() 函数中。具体来说,我需要输入 -t 标志(两次)。

我已经找了好久,找不到任何东西。非常感谢您对此的帮助。也很抱歉这篇文章的长度。:)

干杯

4

3 回答 3

2

如果 sudo passwd root 需要 tty,请尝试 phpseclib 中的 read() / write()。例如。

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('localhost', 22);
$ssh->login('username', 'password');

$ssh->read('[prompt]');
$ssh->write("sudo passwd root\n");
$ssh->read('Password:');
$ssh->write("Password\n");
echo $ssh->read('[prompt]');
?>

实际上,我只是从您的另一篇文章中复制/粘贴:php ssh2_exec not execution 'su' command

看起来你在那里得到了一些帮助,然后停止了跟进?有人建议您需要在命令中添加新行。你试过吗?他们还建议在 phpseclib 支持论坛上发帖。对我来说似乎是一个很好的建议......

于 2011-04-24T00:20:18.150 回答
2

您可以通过调用启用伪终端

$ssh->enablePTY();

在您登录之后,但在执行之前。这将防止它抱怨丢失的 tty。

于 2015-11-23T11:47:35.020 回答
1

我暂时研究了phpseclib Net_SSH2。看起来它使用套接字连接到服务器。所以没有办法通过-t两次。这不是一个ssh电话。

由于您在问题中提到了 libssh2,因此有一个支持它的 PEAR 包装器,可能会使事情变得更容易,该代码目前仅在 SVN 中。PEAR 包装器也被调用Net_SSH2,但与 phpseclib 的不同Net_SSH2(令人困惑)。

在此处查看代码:

要下载它,请使用以下命令进行 svn checkout:

svn co http://svn.php.net/repository/pear/packages/Net_SSH2/trunk/ ./Net_SSH2

小例子:

<?php
require_once './Net_SSH2/Net/SSH.php';
$ssh = new Net_SSH2::factory('LibSSH2', array(
    'login_name' => 'user',
    'password'   => 'pass',
    'hostname'   => 'example.org',
    'command'    => 'su -',
));
$ssh->sshExec($std_output, $std_error);
var_dump($std_output, $std_error);

那会有帮助吗?

于 2011-04-23T17:18:40.477 回答