Обвески для Web-сервера, без которых не обойтись
Евгений Зобнин (j1m@synack.ru)
Сегодня Web-серверы играют важнейшую роль в интернет-инфраструктуре. На них держится все, начиная с сайта Марины Петровны с посещаемостью 3 человека в месяц и заканчивая высоконагруженными проектами YouTube и Twitter. От производительности и безопасности Web-серверов во многом зависит конкурентоспособность сервиса, но чтобы выжать из сервера все, недостаточно одной только тонкой настройки Apache и PHP.
Содержание:
- eAccelerator
- IonCube PHP Encoder
- Web Optimizer
- PHP Intrusion Detection System (PHPIDS)
- Интересные Apache-модули
- Что еще?
- Боковые выносы
Исполнение PHP-скриптов очень сложная задача, создающая огромные нагрузки на Web-сервер. По сути, именно разбор скриптов зачастую является наиболее затратным процессом, происходящим на машине, где крутится сервис. При этом не все Web-дизайнеры и программисты знают, что процесс исполнения PHP-кода (как, впрочем, и кода на любом другом современном интерпретируемом языке) состоит из двух этапов: трансляция кода PHP в байткод виртуальной машины и непосредственное исполнение байткода.
Первая операция в большинстве случаев более сложна и ресурсоемка чем вторая, поэтому разумнее хранить прекомпилированный PHP-байткод в кэше и запускать на исполнение именно его, пропуская процедуру трансляции. К сожалению, стандартный интерпретатор PHP не позволяет проделывать такое, поэтому уже давно существует несколько проектов по созданию PHP-ускорителей, наиболее производительный из которых носит имя eAccelerator.
— это PHP-ускоритель, основанный на коде проекта . Он не только кэширует PHP-код в виде байткода, но и производит его оптимизацию, позволяет хранить кэш на диске и обладает развитой системой настроек.
eAccelerator распространяется в виде PHP-модуля, но доступен в репозиториях далеко не всех дистрибутивов, поэтому мы установим его из исходных текстов. Для этого получим последнюю стабильную версию модуля:
$ cd ~/tmp $ wget http://bart.eaccelerator.net/source/0.9.5.3/eaccelerator-0.9.5.3.tar.bz2 $ tar -xjf eaccelerator-0.9.5.3.tar.bz2 $ cd eaccelerator-0.9.5.3
Установим пакеты, необходимые для сборки ПО из исходников (gcc, binutils и т.д.):
$ sudo apt-get install build-essential
Также нам понадобится пакет php-devel (php5-devel), содержащий утилиту phpize:
$ sudo apt-get install php5-devel
Запускаем процесс сборки:
$ export PHP_PREFIX="/usr" $ $PHP_PREFIX/bin/phpize $ ./configure \ --enable-eaccelerator=shared \ --with-php-config=$PHP_PREFIX/bin/php-config $ make $ sudo make install
Далее узнаем местоположение файла php.ini (в разных дистрибутивах он находится в разных местах):
$ php -i | grep php.ini
И добавляем в него следующие строки:
$ sudo vi /etc/php5/apache2/php.ini extension="eaccelerator.so" // В дисковом кэше будут храниться данные сессий, контент и прекомпилированный код eaccelerator.cache_dir="/tmp/eaccelerator" // Включаем eAccelerator (данная опция может быть полезна, если нужно отключить // кэширование для одного или нескольких виртуальных хостов, пример: // "php_admin_value eaccelerator.enable 0" в соответствующей секции vhost конфига // Web-сервера) eaccelerator.enable="1" // Включаем оптимизатор, который поможет ускорить выполнения кода eaccelerator.optimizer="1" // При каждом обращении проверяем время модификации скрипта, // чтобы определить, нуждается ли он в перекомпиляции или нет eaccelerator.check_mtime="1" // Отключаем журналирование отладочной информации eaccelerator.debug="0" // С помощью этой директивы можно определить, какие PHP-файлы могут быть // кэшированы (например, "*.php *.phtml"), задаем все: eaccelerator.filter="" // Количество памяти (shared memory), выделяемой для кэширования PHP-скриптов eaccelerator.shm_size="16" eaccelerator.shm_max="0" eaccelerator.shm_ttl="0" eaccelerator.shm_prune_period="0" eaccelerator.shm_only="0" // Устанавливаем максимальный уровень сжатия для контентного кэширования eaccelerator.compress="1" eaccelerator.compress_level="9"
Создаем каталог для файлов кэша:
$ mkdir /tmp/eaccelerator $ chmod 0777 /tmp/eaccelerator
Перезапускаем apache:
$ sudo /etc/init.d/apache2 restart
Вот и все. Теперь можно выполнить замер производительности. Разработчики утверждают, что ее прирост может достигать 10-ти раз, однако по личному опыту могу сказать, что зачастую эта цифра становится еще выше.
Идея хранения и запуска байткода вместо оригинального PHP-кода открывает одну интересную возможность: сокрытие исходного кода. Транслировав PHP-код в байткод, мы не только получим прирост производительности, но и существенно усложним процесс исследования и модификации кода.
Сразу оговорюсь: несмотря на то, что eAccelerator и другие аналогичные по функциональности системы и позволяют осуществить трансляцию в байткод, использовать их для защиты PHP-приложения довольно наивно. Стандартная виртуальная машина языка PHP проста, хорошо документирована и не скрывает то, что скрывать бессмысленно, поэтому восстановить изначальный PHP-код из байткода или изменить поведение приложения будет достаточно просто.
Для установки настоящей, стойкой защиты на PHP-скрипты принято применять протекторы, наиболее известные из которых называются Zend Optimizer и IonCube PHP Encoder. Первый — это платный проект разработчиков PHP, защитные техники которого однажды уже показали свою нестойкость (в результате доверие к продукту упало). Второй разрабатывается компанией IonCube, обладает в три раза меньшей ценой и использует гораздо более изощренные техники сокрытия оригинального кода. Ему и будет посвящена остальная часть раздела.
Основные характеристики IonCube PHP Encoder:
- Трансляция PHP-скриптов в байткод (спецификации которого закрыты).
- Шифрование других типов файлов (например XML, шаблоны Smarty, изображения).
-
Генерация лицензионных файлов для ограничения доступа к закодированным файлам (Pro/Cerberus Encoder).
- Обфускация байткода после компиляции.
- Возможность получать файлы форматов ASCII или Binary.
- Использование цифровых сигнатур для защиты скриптов от модификации.
- Защита от вызова закодированных файлов из неавторизованных файлов.
- Совместимость с открытыми расширениями, такими как mmcache и eAccelerator.
-
Возможность создания триальных скриптов, которые перестают работать после истечения определенного срока (Pro/Cerberus Encoder).
-
Защита файлов от запуска на машинах с определенными IP/MAC-адресами и DNS-именами (Pro/Cerberus Encoder).
- Интеграция с IonCube Package Foundry.
- Возможность вставки текстовых аннотаций и других данных в закодированные файлы.
- Чрезвычайно быстрое кодирование (благодаря чему возможно кодирование на лету).
IonCube транслирует PHP-код в байткод для собственной виртуальной машины, проводит оптимизацию, обфускацию, шифрует легко читаемые участки. При этом для исполнения байткода применяется IonCube PHP Loader, включающий в себя виртуальную машину, и потому необходимый везде, где должен быть запущен закодированный PHP-скрипт.
Для восстановления кода, зашифрованного PHP Encoder, взломщику придется вслепую произвести дизассемблирование байткода виртуальной машины (естественно, ни документации, ни исходного кода ВМ никто ему не даст), затем расшифровать зашифрованные данные, разобрать и подчистить код от обфускации и только после этого попытаться восстановить исходный PHP-код. При этом даже если взломщик попытается просто изменить код (например, для отключения проверки на регистрацию), приложение перестанет функционировать из-за несовпадения контрольной суммы в цифровой подписи. Тогда придется менять и ее.
Не возьмусь говорить, что взломать PHP-скрипты, закодированные PHP Encoder, невозможно, но это как раз тот случай, когда затраты не окупают результатов.
IonCube PHP Encoder доступен в виде триальной версии, которую можно получить, следуя инструкциям, опубликованным на странице . Для установки достаточно выполнить пять шагов:
- Зарегистрироваться и скачать последнюю версию PHP Encoder.
-
Распаковать полученный архив и скопировать загрузчик в каталог PHP-модулей (он может быть другим):
$ cd ~/tmp $ tar -xzf ioncube_encoder_evaluation.tar.gz $ cd ioncube_encoder_evaluation $ sudo cp loaders/ioncube_loader_lin_5.3.so /usr/lib/php5/20060613+lfs/
-
Добавить в секцию [PHP] файла php.ini строку:
zend_extension = /usr/lib/php/modules/ioncube_loader_lin_5.3.so
-
Перезапустить индейца:
$ sudo /etc/init.d/apache2 restart
-
Закодировать файлы с помощью команды ioncube_encoder5 (или просто ioncube_encoder в случае PHP4):
$ ~/tmp/incube_encoder5 --obfuscate all оригинал.php \ -o закодированный_скрипт.php
Больше информации об аргументах командной строки ioncube_encoder ты узнаешь из официального руководства пользователя.
Любой web-дизайнер, разработчик или системный администратор, хоть раз занимавшийся оптимизацией содержимого веб-сайта, знает, что этот процесс требует применения множества самых различных техник и кучу времени, которое приходится тратить на рутинные, однообразные действия. Большую часть этих действий, конечно, можно оптимизировать с помощью скриптов и шаблонов конфигурационных файлов, однако различные CMS и Web-сервера могут внести в подход различия, скрипты придется дорабатывать, а конфиги переписывать.
Наверное, именно такие мысли посещали головы российских web-разработчиков из ООО «ВЕБО» незадолго до того, как они приступили к разработке автоматизированной системы оптимизации контента. В результате их работы появился — набор PHP-скриптов, которые выполняют всю рутинную работу по оптимизации контента Web-сайта на лету.
Надо сказать, система получилась весьма функциональная, она уже умеет делать следующее:
- Объединение внешнего и встроенного кода.
- Минимизация файлов (удаление из кода комментариев, незначащих пробелов, символов табуляции, переносов строк с целью уменьшения объема файлов и ускорения их загрузки).
- gzip-сжатие файлов.
- Клиентское кэширование.
- Серверное кэширование.
- Поддержка множественных хостов.
- Автоматическое создание CSS Sprites.
- Автоматическое применение Data:URI.
- Ненавязчивая загрузка JavaScript.
Перефразируя слова авторов, можно сказать, что пользователям Web Optimizer больше не придется натравливать компрессор на каждый имеющийся js-файл, удалять комментарии из HTML-файлов и вытягивать их в одну строку, настраивать кэширование и проделывать многие другие рутинные операции. Все это сделает полностью автоматизированная система, которая проста в установке и не требовательна к ресурсам.
Опять же, если верить словам разработчиков (подкрепленным внушительной таблицей с замерами производительности), то среднее увеличение скорости загрузки страниц, обработанных Web Optimizer, составляет примерно 250% (а в некоторых случаях и до 500%). «Сайты ускоряются в среднем в 2,5 раза (+21 в оценке YSlow, -34% в размере, -43% в количестве внешних объектов)».
Для установки Web Optimizer следует выполнить три простых шага:
- Обзавестись Web-сервером с поддержкой PHP и SSH-доступом (FTP тоже подойдет).
-
Получить последнюю версию Web Optimizer:
$ wget http://web-optimizator.googlecode.com/files/web-optimizer.v0.6.6.zip
-
Распаковать архив в корневой каталог Web-сервера:
$ cd /var/www $ sudo unzip /путь/к/web-optimizer.v0.6.6.zip
Чтобы Web Optimizer смог сохранять кэшированные версии обработанных им файлов, следует установить права на запись на файл web-optimizer/config.webo.php и каталог web-optimizer/cache для пользователя, под которым работает Web-сервер:
$ sudo chmod +w web-optimizer/config.webo.php $ sudo chmod -R +w web-optimizer/cache $ sudo chmod -R www-data:www-data web-optimizer/cache
Все, теперь открываем страницу http://сайт/web-optimizer/index.php в браузере и приступаем к настройке фреймворка. Самый простой путь — довериться системе, ввести логин и пароль администратора и нажать кнопку «Быстрая установка». Web Optimizer пройдется по цепочке расположенных на Web-сервере файлов и создаст их закэшированные сжатые версии. Также он произведет необходимую для последующей работы системы модификацию оригиналов или (если они недоступны для записи) выведет инструкцию об их изменении.
Нажав на оранжевую стрелку в правой стороне экрана, можно произвести так называемую «Обычную установку», которая включает в себя возможность ручного указания опций оптимизации.
PHP Intrusion Detection System (PHPIDS)
Многие из нас применяют системы обнаружения вторжений на своих серверах. Некоторым достаточно сетевых IDS, другие также устанавливают и локальные, однако мало кто применяет Web IDS, предназначенные для «отлова» попыток взлома Web-сайтов.
PHPIDS одна из представительниц таких систем. Это легкая в использовании, быстрая система обнаружения атак, которая умеет ловить разные виды XSS, SQL-инъекции, расщепления запроса (HTTP Response Splitting), проходы по каталогам (Directory traversing), RFE/LFI, DoS, LDAP-инъекции и многое другое. Причем это не просто слова, а реально работающая система, которая способна отбить охоту взлома у 99% злоумышленников. Для сомневающихся открыта специальная страничка, перейдя на которую, любой желающий может попробовать обмануть систему.
PHPIDS представляет собой PHP-библиотеку, которую следует подключать к проекту. В результате все входные данные попадают на ее вход, после чего производится их парсинг и проверка на легальность. В случае обнаружения попытки вторжения, принимающий данные скрипт завершается, формируется отчет и отсылается системному администратору (сохраняется на диске, отсылается разработчикам PHPIDS, вписать нужное).
Установить систему очень просто:
-
Скачиваем последнюю версию PHPIDS с офсайта и распаковываем:
$ cd /tmp $ wget http://php-ids.org/files/phpids-0.6.3.1.tar.bz2 $ tar -xjf phpids-0.6.3.1.tar.bz2 $ sudo mkdir /var/phpids $ sudo mv lib /var/phpids $ cd /var/phpids/lib/IDS $ sudo chown -R www-data:www-data tmp
Обрати внимание, что мы намеренно установили PHPIDS рядом с корневым каталогом Web-сервера (а не в него). Так мы изолировали его каталоги от просмотра посторонними.
-
Открываем конфигурационный файл Config/Config.ini.php и вносим в него необходимые изменения. На данном этапе достаточно модифицировать всего одну опцию:
base_path = /var/phpids/lib/IDS
Все остальные поля файла можно оставить неизменными, PHPIDS и в базовой конфигурации работает на пять с плюсом.
-
Создаем файл phpids.php в корневом каталоге Web-сервера и записываем в него следующее:
$ sudo vi /var/www/phpids.php set_include_path( get_include_path() . PATH_SEPARATOR . '/var/phpids/lib' ); if (!session_id()) { session_start(); } require_once 'IDS/Init.php'; try { /* * Что будем сканировать? */ $request = array( 'REQUEST' => $_REQUEST, 'GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE ); $init = IDS_Init::init(dirname(__FILE__) . \ '/var/phpids/lib/IDS/Config/Config.ini.php'); /* * Инициализируем PHPIDS и читаем результаты проверки */ $ids = new IDS_Monitor($request, $init); $result = $ids->run(); /* * Если обнаружена атака - заносим результат в логи и завершаем работу */ if (!$result->isEmpty()) { echo $result; require_once 'IDS/Log/File.php'; require_once 'IDS/Log/Composite.php'; $compositeLog = new IDS_Log_Composite(); $compositeLog->addLogger(IDS_Log_File::getInstance($init)); $compositeLog->execute($result); die('Attack detected'); } } -
Чтобы PHPIDS проверял все наши PHP-скрипты, добавим файл phpids.php к каждому из них. Для этого откроем php.ini и внесем в него следующую строку:
auto_prepend_file /var/www/phpids.php
То же самое можно сделать при помощи .htaccess:
php_value auto_prepend_file /var/www/phpids.php
-
Перезапускаем апач:
$ sudo /etc/init.d/apache2 restart
Это все. Теперь можешь протестировать PHPIDS, набрав в адресной строке браузера что-нибудь вроде «http://сайт/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E».
Этот раздел посвящен сторонним Apache-модулям, которые ты можешь скачать из Интернета и подключить к своему Web-серверу. Среди них есть как известные и повсеместно используемые модули, так и необычные проекты.
- — ограничение на одновременное количество подключений к Web-серверу.
- — индивидуальный контроль пропускной способности и количества подключений для каждого виртуального хоста.
- — установка и снятие переменных окружения на основе IP-адресов и DNS-имен клиентов.
- — контроль доступа, основанный на черных и белых списках DNSBL.
- — динамический балансировщик нагрузки. Требует mod_proxy.
- — реализация QoS, возможность использования разных приоритетов обработки в зависимости от типа запроса.
- — реализация капчи в виде Apache-модуля. Для своей работы требует библиотеки GD 2.x и Berkeley DB 4.5.
- — конвертирует swf-файлы в HTML для того, чтобы они могли быть проиндексированы поисковыми машинами.
- — показывает текстовые файлы, добавляя к ним хидер и футер (так же, как это сделано при отображении каталогов).
- — валидатор HTML, XML и SGML.
- — интерпретатор bash, встроенный в Apache.
Рассмотренные в статье обвески далеко не все, что было придумано web-разработчиками и программистами в области разгона и защиты Web-сервера. При должном терпении на просторах интернета ты сможешь найти массу проектов, которые позволят твоему серверу выдерживать большие нагрузки и самые изощренные типы атак.
INFO
-
Обфускация — приведение исходного текста или исполняемого кода программы к виду, сохраняющему ее функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции. Другими словами, запутывание кода.
-
добавляет функцию phpsecinfo(), предоставляющую информацию о безопасности PHP-окружения и советы по ее улучшению.
Статья опубликована в январско-февральском номере журнала «Xakep» за 2010 год.





