Журнал LinuxFormat - перейти на главную

LXF81:PHP

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Новая: == PHP Безопасная оболочка == '' Устали от людей, взламывающих ваш элитарный шифр rot26? '''Пол Хадсон''' научит...)
 
м
Строка 55: Строка 55:
 
шифрование и устойчивый метод обмена ключами, но у вас есть возможность снизить планку, если клиент или сервер не понимают сильных алгоритмов. Чтобы изменить свойства подключения используется третий параметр функции ssh2_connect(). Он должен быть массивом, содержащим
 
шифрование и устойчивый метод обмена ключами, но у вас есть возможность снизить планку, если клиент или сервер не понимают сильных алгоритмов. Чтобы изменить свойства подключения используется третий параметр функции ssh2_connect(). Он должен быть массивом, содержащим
 
ключи “kex”, “client_to_server” и “server_to_client”. Значением первого ключа, “kex”, должен выступить алгоритм обмена ключами, который вы
 
ключи “kex”, “client_to_server” и “server_to_client”. Значением первого ключа, “kex”, должен выступить алгоритм обмена ключами, который вы
запрашиваете. Здесь можно указать diffie-hellman-group1-sha1, diffiehellman-
+
запрашиваете. Здесь можно указать diffie-hellman-group1-sha1, diffiehellman-group14-sha1 или diffie-hellman-group-exchange-sha1.
group14-sha1 или diffie-hellman-group-exchange-sha1.
+
  
 
Параметры “client_to_server” и “server_to_client” сами являются массивами, определяющими объявленные алгоритм шифрования (“crypt”),
 
Параметры “client_to_server” и “server_to_client” сами являются массивами, определяющими объявленные алгоритм шифрования (“crypt”),
метод сжатия (“comp”) и метод MAC (“mac”). Например, если вы хоти-
+
метод сжатия (“comp”) и метод MAC (“mac”). Например, если вы хотите использовать довольно небезопасное SSH-соединение (это бывает
те использовать довольно небезопасное SSH-соединение (это бывает
+
 
возможно в доверенной сети, если для вас особенно важна скорость),
 
возможно в доверенной сети, если для вас особенно важна скорость),
 
то вы можете запросить шифрование по алгоритму 3DES вместо AES,
 
то вы можете запросить шифрование по алгоритму 3DES вместо AES,
Строка 89: Строка 87:
 
что приводит к тому что блоки, содержащие один и тот же зашифрованный текст оказываются совершенно непохожи друг на друга.
 
что приводит к тому что блоки, содержащие один и тот же зашифрованный текст оказываются совершенно непохожи друг на друга.
  
Если вы хотите попробовать настройку “comp”, укажите ее в мас-
+
Если вы хотите попробовать настройку “comp”, укажите ее в массивах “client_to_server” и “server_to_client”. В качестве значения
сивах “client_to_server” и “server_to_client”. В качестве значения
+
 
используйте “zlib”.
 
используйте “zlib”.
  
Строка 160: Строка 157:
 
переменной $sftp нам потребовалось, чтобы указать, из какого потока
 
переменной $sftp нам потребовалось, чтобы указать, из какого потока
 
выполнять чтение. И обратите внимание на то, что нам вновь пришлось
 
выполнять чтение. И обратите внимание на то, что нам вновь пришлось
полностью указать полный путь, поскольку по умолчанию поиск выпол-
+
полностью указать полный путь, поскольку по умолчанию поиск выполняется в корневом каталоге.
няется в корневом каталоге.
+
 
===Я заказал безопасный канал===
 
===Я заказал безопасный канал===
 
Нашим последним SSH-трюком будет получение полноценной SSH-
 
Нашим последним SSH-трюком будет получение полноценной SSH-
 
оболочки, которую мы можем читать и писать так, будто это обычный
 
оболочки, которую мы можем читать и писать так, будто это обычный
 
терминал. PHP вновь интерпретирует ее как локальный файл, так что
 
терминал. PHP вновь интерпретирует ее как локальный файл, так что
мы сможем использовать функции fread() and fgets() обычным обра-
+
мы сможем использовать функции fread() and fgets() обычным образом. Требуется только придерживаться одного главного правила – нужно дать удаленному компьютеру время на то, чтобы выполнить нашу
зом. Требуется только придерживаться одного главного правила – нужно дать удаленному компьютеру время на то, чтобы выполнить нашу
+
 
команду, иначе мы будем искать результат до того, как он будет готов.
 
команду, иначе мы будем искать результат до того, как он будет готов.
 
Итак, вот код:
 
Итак, вот код:
Строка 191: Строка 186:
 
писать команды и отсюда же читать результаты.
 
писать команды и отсюда же читать результаты.
  
Для начала выполним главное правило – нам придется исполь-
+
Для начала выполним главное правило – нам придется использовать функцию sleep(), чтобы прервать выполнение на 1 секунду
зовать функцию sleep(), чтобы прервать выполнение на 1 секунду
+
 
и дать серверу время очистить соединение и вывести шапку (строку
 
и дать серверу время очистить соединение и вывести шапку (строку
 
приветствия удаленного пользователя). Затем мы используем цикл
 
приветствия удаленного пользователя). Затем мы используем цикл

Версия 16:55, 10 марта 2008

Содержание

PHP Безопасная оболочка

Устали от людей, взламывающих ваш элитарный шифр rot26? Пол Хадсон научит вас защищаться.

Геродот однажды сказал: “Ни одно расширение не зови счастливым, пока не начал его использовать”. Ну хорошо, он сказал не совсем так, но в любом случае это справедливо: в составе PECL (PHP Extention Community Library) можно найти сотни странных, удивительных и великолепных расширений, ждущих когда же мы их попробуем, однако, пока вы не узнаете о существовании одного из них, пока не попробуете сами им воспользоваться – оно для вас все равно что не существует.

Эта статья посвящена изучению одной из скрытых драгоценностей PECL – расширению SSH2. Оно позволяет вам создавать безопасные зашифрованные каналы связи через Интернет, используя PHP, а затем использовать их для выполнения команд оболочки, переноса файлов и всего остального, что обычно делается при помощи SSH. Да, в работе через Web содержится определенный риск, но если вы а) поместили поле ввода пароля на странице и б) требуете указывать его для установки SSH-соединения, то вы находитесь в относительной безопасности. С другой стороны, если вы пишите скрипты, которые будете вызывать из локальной консоли, это расширение оказывается мощным средством для выполнения автоматических запросов к удаленным серверам вдали от назойливых взглядов хакеров.

Подключение

Я почти уверен, что расширение PHP SSH у вас не установлено, что не удивительно, поскольку оно не распространяется вместе с PHP, а библиотека от которой оно зависит (libssh2) очень редко включается в состав дистрибутивов. После того, как вы пройдете все этапы установки (они описаны во врезке справа), вам потребуется выполнить маленький тест, просто чтобы убедиться, что все в порядке. Попробуйте что-то вроде:

<?php
$conn = ssh2_connect(“192.168.133.98”, 22);
if (!$conn) die(“Could not connect!);
echo ssh2_fingerprint($conn);
?>

Здесь вы видите две SSH-функции: ssh2_connect(), которая выполняет подключение к серверу (первый параметр) по указанному порту (второй параметр) и ssh2_fingerprint(), которая принимает подключение в качестве своего единственного параметра и выводит MD5-отпечаток сервера. Этот отпечаток никогда не меняется. В результате довольно легко опознать попытку атаки “man-in-the-middle” (при которой хакер пререхватывает ваше соединение вместо сервера, чтобы узнать пароль), поскольку полученное значение будет отличаться от ожидаемого.

Запустив этот сценарий, вы должны увидеть в качестве результата отпечаток для своего сервера. Он должен полностью совпадать с тем, который вы получаете, набрав ssh localhost на удаленной консоли за тем исключением, что при работе в командной строке SSH разделяет отпечаток на двухсимвольны блоки, отделенные двоеточиями.

Если вы подключаетесь, указав только IP-адрес (или доменное имя сервера) и порт, то библиотека SSH автоматически выберет устойчивое шифрование и устойчивый метод обмена ключами, но у вас есть возможность снизить планку, если клиент или сервер не понимают сильных алгоритмов. Чтобы изменить свойства подключения используется третий параметр функции ssh2_connect(). Он должен быть массивом, содержащим ключи “kex”, “client_to_server” и “server_to_client”. Значением первого ключа, “kex”, должен выступить алгоритм обмена ключами, который вы запрашиваете. Здесь можно указать diffie-hellman-group1-sha1, diffiehellman-group14-sha1 или diffie-hellman-group-exchange-sha1.

Параметры “client_to_server” и “server_to_client” сами являются массивами, определяющими объявленные алгоритм шифрования (“crypt”), метод сжатия (“comp”) и метод MAC (“mac”). Например, если вы хотите использовать довольно небезопасное SSH-соединение (это бывает возможно в доверенной сети, если для вас особенно важна скорость), то вы можете запросить шифрование по алгоритму 3DES вместо AES, используемого по умолчанию. Пример кода:

<?php
$methods = array(
“client_to_server” => array(crypt=> “3des-cbc”),
“server_to_client” => array(crypt=> “3des-cbc”)
);
$conn = ssh2_connect(“192.168.133.98”, 22, $methods);
if (!$conn) die(“Could not connect!);
$methods_neg = ssh2_methods_negotiated($conn);
echo “Keys negotiated with: {$methods_neg[‘kex’]}\n”;
echo “Client-to-server uses these methods:\n”;
echo “ Encryption: {$methods_neg[“client_to_server”][crypt]}\n”;
echo “ Compression: {$methods_neg[“client_to_server”][“comp”]}\n”;
echo “Server-to-client uses these methods:\n”;
echo “ Encryption: {$methods_neg[“server_to_client”][crypt]}\n”;
echo “ Compression: {$methods_neg[“server_to_client”][“comp”]}\n”;
?>

Массив $methods содержит ключи “client_to_server” и “server_to_ client”, которые в свою очередь содержат массивы с ключом “crypt” и значением “3des-cbc”. CBC расшифровывается как Cipher Block Chaining (блочная передача зашифрованного текста), при его использовании передаваемые данные разбиваются на маленькие блоки и к каждому блоку перед шифрованием применяется операция XOR с предыдущим блоком, что приводит к тому что блоки, содержащие один и тот же зашифрованный текст оказываются совершенно непохожи друг на друга.

Если вы хотите попробовать настройку “comp”, укажите ее в массивах “client_to_server” и “server_to_client”. В качестве значения используйте “zlib”.

В нашем коде появляется новая функция, ssh2_methods_ negotiated(). Она возвращает массив, содержащий описание алгоритмов обмена ключами, сжатия и MAC (Message Authentication Code, код подтверждения подлинности сообщения), которые были в реальности использованы при этом подключении к удаленному серверу. Затем мы просто вывели на печать некоторые из полученных значений, но вы, возможно, захотите выполнить какие-то свои проверки этих значений, чтобы убедиться, что уровень безопасности вас устраивает.

Отправьте этот файл

Как любой другой пакет SSH, расширение SSH для PHP поддерживает SFTP и SCP, методы безопасной передачи файлов. Оба они используют одни и те же алгоритмы шифрования и поэтому одинаково безопасны, вся разница в том, хотите ли вы полноценное соединение напоминающее FTP, или же вам нужно только читать и записывать файлы в стиле cp.

Давайте сначала посмотрим на реализацию SCP, который был разработан чтобы осуществлять копирование файлов по принципу команды cp, но только через защищенное интернет-соединение. Рассмотрим две новых функции: ssh2_auth_password() выполняет аутентификацию нашего соединения, а ssh2_scp_send() копирует локальный файл на удаленный сервер. Для начала давайте создадим локальный файл, выполнив следующую команду:

echo “Hello, world” > hello.txt

А теперь передадим наше приветствие на сервер. Вам потребуется указать имя пользователя и пароль для подключения к серверу, для этого просто замените в следующем сценарии строки “username” и “password” на правильные значения.

<?php
$conn = ssh2_connect(“192.168.133.98”, 22);
if (!$conn) die(“Could not connect!);
ssh2_auth_password($conn, “username”, “password”);
ssh2_scp_send($conn, “hello.txt”,/home/<имя удаленного
пользователя>/hello.txt”);
?>

Обратите внимание, вам нужно указать будущее местоположение файла на удаленном сервере, в нашем случае это /home/<имя удаленного пользователя>/hello.txt. Получение файлов происходит так же просто, достаточно использовать функцию ssh2_scp_recv() и поменять местами второй и третий параметры.

ssh2_scp_recv($conn,/home/yourremoteusername/hello.txt”,”hello.txt”)

Второй способ передачи файлов – это использование SFTP, который позволяет выполнять FTP-подобные команды (например, mkdir, stat и так далее) по защищенному SSH-каналу. И, что более важно, SFTP в PHP реализован как оболочка для fopen, что значит вы можете использовать любые файловые функции PHP. Например:

<?php
$conn = ssh2_connect(“192.168.133.98”, 22);
if (!$conn) die(“Could not connect!);
ssh2_auth_password($conn, “username”, “password”);
$sftp = ssh2_sftp($conn);
$file = file_get_contents(“ssh2.sftp://$sftp/home/paul/hello.txt”);
echo $file;
?>

Итак, мы подключились к удаленному серверу и авторизовались на нем, указав имя пользователя и пароль. Затем мы вызвали функцию ssh2_sftp() для полученного соединения, которая выполнила SFTP- подключение и вернула его дескриптор. Именно этот номер потребуется для использования обычных файловых функций, так что мы присвоили его переменной $sftp. Теперь мы можем вызвать функцию file_get_ contents(), указав в ssh2.sftp:// в качестве протокола, и PHP прочитает содержимое файла через прозрачное SSH-подключение. Значение переменной $sftp нам потребовалось, чтобы указать, из какого потока выполнять чтение. И обратите внимание на то, что нам вновь пришлось полностью указать полный путь, поскольку по умолчанию поиск выполняется в корневом каталоге.

Я заказал безопасный канал

Нашим последним SSH-трюком будет получение полноценной SSH- оболочки, которую мы можем читать и писать так, будто это обычный терминал. PHP вновь интерпретирует ее как локальный файл, так что мы сможем использовать функции fread() and fgets() обычным образом. Требуется только придерживаться одного главного правила – нужно дать удаленному компьютеру время на то, чтобы выполнить нашу команду, иначе мы будем искать результат до того, как он будет готов. Итак, вот код:

<?php
$conn = ssh2_connect(“192.168.133.98”, 22);
if (!$conn) die(“Could not connect!);
ssh2_auth_password($conn, “username”, “password”);
$stdio = ssh2_shell($conn);
sleep(1);
while($line = fgets($stdio)) echo $line;
fwrite($stdio, “uname -a\n”);
sleep(1);
while($line = fgets($stdio)) echo $line;
fclose($stdio);
?>

Все вплоть до вызова ssh2_shell() остается прежним. Новая для нас функция ssh2_shell() принимает SSH-соединение в качестве параметра и возвращает дескриптор, который указывает на стандартный поток ввода и стандартный поток вывода SSH-оболочки, на который программы выводят результаты своей работы. Именно сюда мы должны писать команды и отсюда же читать результаты.

Для начала выполним главное правило – нам придется использовать функцию sleep(), чтобы прервать выполнение на 1 секунду и дать серверу время очистить соединение и вывести шапку (строку приветствия удаленного пользователя). Затем мы используем цикл while, состоящий из одной строчки, чтобы прочитать и показать весь текст, переданный сервером (“Welcome to XYZServer!” и так далее). После того, как приглашение прочитано, мы пишем нашу команду “uname –a”. Она показывает системную информацию о компьютере, на котором запущена, такую как версия ядра, архитектура процессора и так далее.

После второго ожидания, пока эта команда отработает, мы делаем еще один однострочный цикл while и показываем полученные от сервера данные. В конце мы закрываем поток командой fclose(), чтобы прибраться за собой и на этом наш сценарий заканчивается. Красиво, правда?


Инструкции по установке SSH для PHP

  1. Установите OpenSSL и его библиотеку разработчика: libssl-dev или libssl-devel.
  2. Вытащите libssh2 из каталога Magazine/PHP вашего диска (ищите файл libssh2-0.13.tar.gz). Распакуйте его, выполните команду ./configure, а затем переключитесь на суперпользователя и запустите make all install.
  3. Возьмите расширение PHP SSH2 из каталога Magazine/PHP вашего диска (файл ssh2-0.10.tgz), распакуйте и запустите phpize, ./configure --with-ssh2, и, наконец, make. В результате вы получите файле ssh2.so в каталоге modules. Его нужно будет скопировать в ваш каталог расширений PHP.
  4. Выполните php –i | grep ini. Эта команда покажет вам местоположение файла php.ini, скорее всего, он находится в /etc/php.ini или /usr/local/lib/php.ini. Если у вас нет php.ini, то вам потребуется скопировать php.inirecommended из исходного дистрибутива PHP установленной у вас версии.
  5. Откройте файл php.ini и найдите в нем строчку ‘extension_dir’. Скорее всего, она будет показывать на примерно такой каталог: /usr/local/lib/php/extensions/.
  6. Поскольку вы все еще находитесь в php.ini, поищите в нем слово ‘dll’, и вы попадете в подраздел с описанием расширений. Вам нужно добавить туда вот такую строчку: extension=ssh2.so.
  7. Сохраните php.ini, а затем перенесите файл modules/ssh2.so, полученный на третьем шаге в каталог с расширениями PHP
  8. Запустите команду php –m. В полученном списке вы увидите ssh2.

Если нет, то, видимо, один из шагов вам не удался...

Персональные инструменты
купить
подписаться
Яндекс.Метрика