PHP имеет библиотеку SSH2, которая обеспечивает доступ к ресурсам (оболочка, удаленное выполнение, туннелирование, передача файлов) на удаленной машине с использованием безопасного криптографического транспорта. Объективно, это трудоемкая и очень разочаровывающая задача для разработчика, чтобы реализовать ее из-за ее огромных возможностей конфигурации и сложного API с небольшим количеством документации.
Пакет phpseclib ( PHP Scuure C ommunications Lib rary) имеет дружественный к разработчику API. Он использует некоторые необязательные расширения PHP, если они доступны, и в противном случае использует внутреннюю реализацию PHP. Чтобы использовать этот пакет, вам не нужны никакие не установленные по умолчанию расширения PHP.
Установка
composer require phpseclib/phpseclib
Это установит самую последнюю стабильную версию библиотеки через Composer .
Случаи использования
Прежде чем погрузиться вслепую, я бы хотел перечислить несколько вариантов использования, подходящих для использования этой библиотеки:
- Выполнение сценариев развертывания на удаленном сервере
- Загрузка и выгрузка файлов через SFTP
- Динамическая генерация ключей SSH в приложении
- Отображение вывода в реальном времени для удаленных команд, выполняемых на сервере
- Тестирование соединения SSH или SFTP
Подключение к удаленному серверу
Используя phpseclib , вы можете подключиться к удаленному серверу любым из следующих способов аутентификации:
- Ключ RSA
- Защищенный паролем ключ RSA
- Имя пользователя и пароль ( не рекомендуется )
Ключ RSA
Мы предполагаем, что у вас уже есть безопасный ключ RSA . Если вы не знакомы с созданием безопасной пары ключей RSA, вы можете прочитать эту статью . Для объяснения видео вы можете обратиться к разделу Создание и использование ключей SSH с серверов для хакеров.
Чтобы войти на удаленный сервер с использованием аутентификации по ключу RSA :
namespace App;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SSH2;
$key = new RSA();
$key->loadKey(file_get_contents('privatekey'));
//Remote server's ip address or hostname
$ssh = new SSH2('192.168.0.1');
if (!$ssh->login('username', $key)) {
exit('Login Failed');
}
Защищенный паролем ключ RSA
Если ваши ключи RSA защищены паролем, не беспокойтесь. Phpseclib позаботится об этом конкретном случае использования:
namespace App;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SSH2;
$key = new RSA();
$key->setPassword('your-secure-password');
$key->loadKey(file_get_contents('privatekey'));
//Remote server's ip address or hostname
$ssh = new SSH2('192.168.0.1');
if (!$ssh->login('username', $key)) {
exit('Login Failed');
}
Имя пользователя и пароль
Кроме того, чтобы войти на удаленный сервер, используя имя пользователя и пароль (мы не рекомендуем эту практику):
namespace App;
use phpseclib\Net\SSH2;
//Remote server's ip address or hostname
$ssh = new SSH2('192.168.0.1');
if (!$ssh->login('username', 'password')) {
exit('Login Failed');
}
Для других опций, таких как Без Аутентификации или Многофакторной аутентификации, пожалуйста, обратитесь к документации
Выполнение команд на удаленном сервере
Код для выполнения команд на удаленном сервере довольно прост. Вы вызываете метод $ssh->exec($cmd)
namespace App;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SSH2;
$key = new RSA();
$key->loadKey(file_get_contents('privatekey'));
//Remote server's ip address or hostname
$ssh = new SSH2('192.168.0.1');
if (!$ssh->login('username', $key)) {
exit('Login Failed');
}
$ssh->exec('ls -la');
Выполнение нескольких команд на удаленном сервере
В реальных приложениях мы редко выполняем одну команду. Нам часто нужно обходить сервер с помощью cd
Если вы попытаетесь выполнить несколько команд на удаленном сервере, как показано ниже, это не даст вам желаемого результата:
$ssh->exec('pwd'); //outputs /home/username
$ssh->exec('cd mysite.com');
$ssh->exec('pwd'); //outputs /home/username
Причина вышеизложенного заключается в том, что вызов метода exec
exec
Чтобы выполнить несколько команд без потери состояния:
$ssh->exec('cd /home/username; ls -la'); //Lists all files at /home/username
Вы можете добавить столько команд, сколько пожелаете, с помощью точки с запятой или символа новой строки PHP_EOL
Например, если вы хотите запустить скрипт полного развертывания для Laravel:
$ssh->exec(
"git pull origin master" . PHP_EOL
. "composer install --no-interaction --no-dev --prefer-dist" . PHP_EOL
. "composer dump-autoload -o" . PHP_EOL
. "php artisan optimize" . PHP_EOL
. "php artisan migrate --force"
);
Выход при первой ошибке
В приведенном выше сценарии весь набор команд выполняется как один сценарий оболочки. Каждая команда будет выполнена, даже если некоторые из них потерпят неудачу, как в обычном сценарии оболочки. По умолчанию это нормально, но если нам нужно выйти при первой ошибке, мы должны изменить наш bash-скрипт. Это не что-то особенное для phpseclib , это связано со сценариями bash.
Если вы поместите опцию set -e
Например, измененная версия вышеуказанного сценария развертывания будет
$ssh->exec(
"set -e" . PHP_EOL
. "git pull origin master" . PHP_EOL
. "composer install --no-interaction --no-dev --prefer-dist" . PHP_EOL
. "composer dump-autoload -o" . PHP_EOL
. "php artisan optimize" . PHP_EOL
. "php artisan migrate --force"
);
Приведенный выше сценарий завершится, если любая из команд приведет к ошибке.
Сбор выходных
Метод exec
$output = $ssh->exec('ls -la');
echo $output;
Иногда, однако, он не возвращает весь вывод. Вы можете преодолеть это, передав закрытие как второй аргумент методу exec
$ssh->exec(
$deployment_script, function ($str) {
$output .= $str;
});
echo $output;
Примечание. Вывод ошибки, если таковой имеется, также будет возвращен методом exec
Отображение живого выхода
Если вы хотите выполнить скрипт с помощью консольных команд и отобразить вывод в реальном времени, вы можете добиться этого, отображая вывод в базовом замыкании.
$ssh->exec($deployment_script, function ($str) {
echo $str;
});
Если вы хотите отобразить его в веб-браузере, вам нужно очистить (отправить) выходной буфер с помощью ob_flush()
$ssh->exec(
$deployment_script, function ($str) {
echo $str;
flush();
ob_flush();
});
Другие параметры конфигурации
Также возможно установить много других доступных параметров конфигурации. Вы можете назвать их как $ssh->{option}
Например: $ssh->setTimeout(100)
Все варианты, которые мы еще не рассмотрели, представлены в таблице ниже:
вариант | Случай использования |
---|---|
setTimeout($seconds) |
$ssh->exec('ping 127.0.0.1'); на хосте Linux никогда не вернется и будет работать бесконечно. setTimeout() Установка $timeout |
write($cmd) |
Вводит команду в интерактивную оболочку. |
read() |
Возвращает вывод интерактивной оболочки |
isTimeout() |
Верните true, если результат последних $ssh->read() $ssh->exec() В противном случае он вернет false. |
isConnected() |
Возвращает true, если соединение все еще активно |
enableQuietMode() |
Подавляет stderr, поэтому ошибки не возвращаются |
disableQuietMode() |
Включает в вывод stderr |
isQuiteModeEnabled() |
Возвращает true, если тихий режим включен |
enablePTY() |
Включить request-pty при использовании exec() |
disablePty() |
Отключить request-pty при использовании exec() |
isPTYEnabled() |
Возвращает true, если request-pty включен |
getLog() |
Возвращает журнал пакетов, которые были отправлены и получены. |
getServerPublicHostKey() |
Возвращает открытый ключ сервера. Возвращает false, если подпись сервера не подписана правильно с открытым ключом хоста. |
getExitStatus() |
Возвращает состояние выхода команды SSH или false. |
getLanguagesClient2Server() |
Возвращать список языков, которые поддерживает сервер, при получении материала от клиента. |
getLanguagesServer2Client() |
Возвращать список языков, которые поддерживает сервер, при отправке материала клиенту. |
getCompressionAlgorithmsServer2Client() |
Возвращает список алгоритмов сжатия, которые поддерживает сервер, при отправке содержимого клиенту. |
getCompressionAlgorithmsClient2Server() |
Возвращает список алгоритмов сжатия, поддерживаемых сервером, при получении данных от клиента. |
getMACAlgorithmsServer2Client() |
Возвращает список алгоритмов MAC, которые поддерживает сервер, при отправке материала клиенту. |
getMACAlgorithmsClient2Server() |
Возвращает список алгоритмов MAC, поддерживаемых сервером, при получении данных от клиента. |
getEncryptionAlgorithmsServer2Client() |
Возвращает список алгоритмов шифрования (симметричного ключа), которые поддерживает сервер, при отправке данных клиенту. |
getEncryptionAlgorithmsClient2Server() |
Возвращает список алгоритмов шифрования (симметричного ключа), которые поддерживает сервер, при получении данных от клиента. |
getServerHostKeyAlgorithms() |
Возвращает список алгоритмов хост-ключа (открытого ключа), поддерживаемых сервером. |
getKexAlgorithms() |
Возвращает список алгоритмов обмена ключами, которые поддерживает сервер. |
альтернативы
- LIBSSH2 — библиотека SSH — библиотека обеспечивает аналогичную функциональность, но ее использование немного менее интуитивно понятно , и для этого требуется, чтобы на сервере была установлена libssh2 , чего нет у большинства общих хостов.
- Компонент процесса — компонент Symfony для написания собственного скрипта для подключения и выполнения команд — как вы это делаете в обычном терминале. Это ограничивает нас в параметрах конфигурации, которые нам может потребоваться установить. Для достижения той же функциональности, что и описанные выше методы конфигурации, нам потребуется Process глубокое знание bash. Однако, если в вашем сценарии использования используется только локальный сценарий, это может оказаться полезным компонентом.
Резюме
В этой статье мы представили phpseclib , пакет, который предоставляет альтернативу для SSH2 . Мы рассмотрели параметры конфигурации, необходимые для начала работы, и приведенная выше таблица должна помочь вам заполнить пробелы и дать обзор других доступных параметров конфигурации.
Подробное описание взаимодействия на основе ключей см. В нашем предыдущем руководстве .
Как вы выполняете удаленные команды? Можете ли вы вспомнить какие-либо дополнительные варианты использования этой библиотеки? Кто они такие? Дайте нам знать об этом в комментариях!