процесс открытого взаимодействия
Вот чего я пытаюсь достичь: откройте оболочку (korn или bash, не имеет значения), из этой оболочки я хочу открыть ssh-соединение (ssh user@host
). В какой-то момент, скорее всего, произойдет, что мне будет предложено ввести пароль, или меня могут спросить, уверен ли я, что хочу подключиться (оскорбительные ключи).
Прежде чем кто-нибудь спросит: да, я знаю, что есть плагин для вызовов ssh2 exec, но серверы, над которыми я работаю, не поддерживают его и вряд ли будут это делать.
Вот что я пробовал до сих пор:
$desc = array(array('pipe','r'),array('pipe','w'));//used in all example code
$p = proc_open('ssh user@host',$desc,$pipes);
if(!is_resource($p)){ die('@!#$%');}//will omit this line from now on
sleep(1);//omitting this,too but it's there every time I need it
Затем я попытался прочитать вывод консоли (stream_get_contents($pipes[1])
), чтобы увидеть, что мне нужно передать дальше (либо пароль, да, либо возврат 'connection failed: '.stream_get_contents($pipes[1])
и proc_close $p.
Это дало мне следующую ошибку:
Псевдотерминал не будет выделен, поскольку стандартный ввод не является терминалом.
Итак, я, хотя ssh был вызван в контексте php://
потока ввода-вывода, кажется правдоподобным объяснением вышеупомянутой ошибки.
Далее: Я подумал о моем первый вопрос SO и решил, что было бы неплохо сначала открыть оболочку bash/ksh:
$p = proc_open('bash',$desc,$pipes);
И возьмите это оттуда, но я получил точно такое же сообщение об ошибке, только на этот раз скрипт перестал работать, но ssh запустился. Поэтому я преисполнился надежды, потом почувствовал себя глупо и, в конце концов, отчаялся:
$p=proc_open('bash && ssh user@host',$desc,$pipes);
После нескольких секунд ожидания я получил следующую ошибку:
Неустранимая ошибка PHP: Разрешенный объем памяти 134217728 байт исчерпан (пытался выделить 133693440 байт)
Стек вызовов продолжает выводить строку stream_get_contents, даже в моей последней отчаянной попытке:
#!/path/to/bin/php -n
<?php
$p = proc_open('bash && ssh user@host',array(array('pipe','r'),array('pipe','w')),$ps);
if (!is_resource($p))
{
die('FFS');
}
usleep(10);
fwrite($ps[0],'yes'."\n");
fflush($ps[0]);
usleep(20);
fwrite($ps[0],'password'."\n");
fflush($ps[0]);
usleep(20);
fwrite($ps[0],'whoami'."\n");
fflush($ps[0]);
usleep(2);
$msg = stream_get_contents($ps[1]);
fwrite($ps[0],'exit'."\n");
fclose($ps[0]);
fclose($ps[1]);
proc_close($p);
?>
Я знаю, что это беспорядок, много fflush
и избыточности, но суть в том, что я знаю, что это соединение сначала запросит у меня ключи, а затем попросит пароль. Я предполагаю, что поток в $pipes[1] содержит ssh-соединение, поэтому его содержимое огромно. что мне тогда нужно, так это труба внутри трубы... возможно ли это вообще? Должно быть, я что-то упускаю, что хороша труба, если это невозможно...
Я предполагаю, что команда proc_open изначально неверна (ошибка: Сломанная труба). Но я действительно не вижу другого способа обойти первую ошибку... есть какие-нибудь мысли? Или задавайте дополнительные вопросы, если вышеприведенная тирада совсем не ясна (что, вероятно, не так).
1 answers
Прежде чем кто-нибудь спросит: да, я знаю, что есть плагин для вызовов ssh2 exec, но серверы, над которыми я работаю, не поддерживают его и вряд ли будут это делать.
На самом деле их два. Модуль PECL, который представляет собой PITA, который все равно не установлен на большинстве серверов, и phpseclib, чистая реализация PHP SSH2. Пример его использования:
<?php
include('Net/SSH2.php');
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
exit('Login Failed');
}
echo $ssh->exec('pwd');
echo $ssh->exec('ls -la');
?>