SSH может передавать данные посредством технологии шифрования онлайн-пакетов; с помощью SSH все передаваемые данные могут быть зашифрованы. Даже если кто-то перехватит данные, никакой полезной информации получить невозможно. При этом данные сжимаются, что значительно ускоряет скорость передачи. Короче говоря, благодаря использованию SSH можно обеспечить относительно безопасную и эффективную передачу данных.
Однако не все знают, что PHP может подключаться к SSH и выполнять удаленные команды, но это очень полезно. Поскольку мы можем использовать PHP по-разному, у него есть множество настроек для управления его поведением. Большой набор дополнительных параметров позволяет использовать PHP для самых разных целей, но это также означает, что сочетание этих параметров и конфигурации на стороне сервера может создать некоторые проблемы с безопасностью. Автор использовал SSH в приложении PHP CLI. Я использовал его из cronjobs, но поначалу это было не очень просто. Можно сказать, что это было довольно сложно. Руководство по безопасному использованию функций Shell2 не очень практично. Автор провел много экспериментов, прежде чем написать сегодня эту небольшую статью. Надеюсь, что после ее прочтения вы сэкономите некоторое время при настройке PHP.
В этой статье мне нужно предположить, что
вы используете операционную систему Debian/Ubuntu. Если вы не используете Debian/Ubuntu, вам может потребоваться заменить соответствующее содержимое этой статьи менеджером пакетов, предоставляемым вашим дистрибутивом Linux.
Вы используете PHP5. Если вы не используете PHP5, вместо этого вы можете использовать PHP4.
У вас есть базовые знания PHP и администрирования серверов.
У вас уже установлен PHP.
Предварительные условия
Пакеты установки
Сначала давайте установим следующие пакеты:
sudo aptitude update
sudo aptitude install php5-dev php5-cli php-pear buid-essential
openssl-dev zlib1g-dev
Установка завершена, переходим к следующему шагу.
Компиляция libssh2
После загрузки Libssh2 с веб-сайта sourceforge нам нужно скомпилировать ее, но не волнуйтесь, вам просто нужно сделать следующее:
cd /usr/src
wget
// войти на server1.example.com через порт 22,
если ( !($con = ssh2_connect("server1.example.com", 22))){
echo "fail: невозможно установить соединениеn"
} else {
// попытаемся пройти аутентификацию с именем пользователя root, паролем secretpassword
if(! ssh2_auth_password ($con, "root", "secretpassword")) {
echo "не удалось: невозможно пройти аутентификациюn"
} else {
// хорошо, мы вошли!
echo "окей: вошли...n" ;
// выполнить команду
if(!($stream = ssh2_exec($con, "ls -al" )) ){
echo "fail: невозможно выполнить командуn"
} else{
// собрать возвращаемые данные из
командыstream_set_blocking ($stream, true);
$data = "";
while($buf = fread($stream,4096)) {
$data .= $buf;
}
fclose($stream }
)
;
Второй метод: Shell
Таким же образом вы можете написать функцию или класс для следующего кода. Однако в этой статье представлены только основные понятия:
if (!function_exists("ssh2_connect")) die("функция ssh2_connect не существует")
// вход в систему на сервере server1.example.com через порт 22
if(!($con = ssh2_connect ("server1.example.com", 22))){
echo "Ошибка: невозможно установить соединениеn";
} else {
// пытаемся пройти аутентификацию с именем пользователя root, паролем secretpassword
if(!ssh2_auth_password($con, "root", "secretpassword")) {
echo "fail: невозможно пройти аутентификациюn"
} else {
// хорошо, мы вошли!
echo "ok: вошли в систему...n"
;
оболочка
if (!($shell = ssh2_shell($con, 'vt102', null, 80, 40, SSH2_TERM_UNIT_CHARS))){
echo "сбой: невозможно установить оболочкуn"
} else{
stream_set_blocking($shell, true) ;
// отправим команду
fwrite($shell,"ls -aln")
;
// & соберем возвращаемые данные
$data = "";
while( $buf = fread($shell,,4096) ){
$data .= $buf;
}
fclose($shell);
}
}
}
Совет:
иногда сервер занят или возникает ошибка соединения, а в буфере нет данных, и PHP-скрипт прекращает вывод данных. команда (даже если команда не завершена!) для сбора данных. Для этого вы можете сделать следующее:
ssh2_exec($con, 'ls -al; echo "__COMMAND_FINISHED__"' );
Теперь в вашем цикле, который постоянно проверяет буфер, просто посмотрите на COMMAND_FINISHED. Потому что тогда вы знаете, что у вас есть все данные. Чтобы избежать бесконечных циклов (бесконечных циклов), вы можете использовать ограничение по времени ожидания в 10 секунд:
$time_start = time();
$data = "";
while( true ){
$data .= fread($stream, 4096) ;
if( strpos($data,"__COMMAND_FINISHED__") !== false){
echo "окей
: команда завершенаn"
}
if( (time()-$time_start) > 10 ){
echo "fail: timeout было достигнуто 10 секундn";
break;
}
}
В приведенном выше примере лучше установить для параметраstream_set_blocking значение false.
Отправка файлов через SSH
ssh2_scp_send($con, "/tmp/source.dat", "/tmp/dest.dat", 0644);
Если это не работает должным образом,
проверьте следующие аспекты:
Следуйте этой статье, чтобы проверить каждый шаг. вашей операции
. На стороне сервера в sshd_config необходимо включить «PasswordAuthentication yes». Значение по умолчанию на большинстве серверов — «да», но в некоторых случаях вам может потребоваться добавить в файл следующую строку, чтобы включить эту функцию самостоятельно:
/etc/ssh/sshd_config:
# Измените значение на «да», чтобы включить туннелируемые пароли в виде открытого текста
.
Если вы вносите изменения, вам необходимо перезапустить SSH:
/etc/init.d/ssh restart