воскресенье, 30 августа 2015 г.

php5-fpm и chroot

В php5-fpm имеется множество разных средств обеспечения безопасности веб-приложений. Во-первых, каждое приложение можно запустить в отдельном пуле, от имени отдельного системного пользователя. Во-вторых, можно зафиксировать некоторые настройки php при помощи директив php_admin_value и php_admin_flag. В-третьих, можно запретить веб-приложению использовать определённые функции php при помощи директивы php_admin_value[disable_functions]. В-четвёртых, при помощи директивы php_admin_value[open_basedir] можно ограничить список каталогов, в пределах которых будет работать веб-приложение.

Для параноиков же предусмотрен ещё один способ защиты - запуск веб-приложения внутри chroot-среды. Этот режим ценен тем, что позволяет защитить систему от взломщиков, пытающихся воспользоваться локальными уязвимостями, то есть уязвимостями установленного в системе программного обеспечения. В идеале, в chroot-среде должен иметься только необходимый для работы веб-приложения минимум файлов, программ и библиотек. Уязвимость в программе внутри chroot-окружения не окажет никакого влияния на файлы за его пределами. Также хорошо бы было защититься от сетевой активности, не характерной для штатной работы веб-приложения. Например, от возможности отправлять куда-то спам. Но это уже можно попробовать реализовать при помощи модуля owner для iptables. А вот если уязвимости есть в ядре системы, то воспользоваться ими, по идее, можно даже из chroot-среды.

Для поиска проблем при работе веб-приложений в chroot-среде неоценимую помощь мне оказали две программы: strace и ltrace. Первая позволяет следить за системными вызовами, выполняемыми отслеживаемым процессом, а вторая - за вызовами библиотечных функций. Мне оказалось достаточным знать о всего двух опциях этих программ:
  • -p - позволяет указать идентификатор процесса, за которым нужно следить. Эту опцию можно указать несколько раз, тогда будут отслеживаться системные вызовы (или вызовы библиотечных функций) из всех указанных процессов.
  • -f - позволяет отслеживать системные вызовы (или вызовы библиотечных функций) порождённых процессов.
Насколько я понял, для работы веб-приложений на php в chroot-среде достаточно добавить в неё разделяемые библиотеки libnss и минимальные настройки для них. Кроме того, нужно создать каталоги для хранения сеансов php и временных файлов. Ещё нужны файлы временных зон. Наконец, нужно устройство /dev/urandom. Возможно каким-то другим приложениям понадобится что-то ещё. Выяснить это можно при помощи упомянутых выше утилит strace и ltrace.

Для работы веб-приложений с базами данных MySQL и PostgreSQL нужно в настройках веб-приложения поменять адрес сервера localhost на 127.0.0.1, поскольку при указании localhost будет предпринята попытка подключения к Unix-сокету, которого в chroot-среде нет. При замене адреса сервера на 127.0.0.1 подключение будет осуществляться на TCP-порт.

Многие веб-приложения на PHP используют функцию mail для отправки писем с помощью sendmail или утилит, заменяющих sendmail. Чтобы отправка почты работала в chroot-окружении, нужно установить в неё альтернативу sendmail. Я попробовал воспользоваться для этих целей утилитами esmtp и msmtp. Обе утилиты мне удалось настроить для отправки почты с аутентификацией, но вот настраивать шифрование по протоколу TLS мне уже было лень, т.к. для его работы в chroot-среду нужно положить дополнительные файлы - список доверенных сертификатов и сами сертификаты.

Поскольку описание настройки chroot-среды в блоге получилось бы очень объёмным, я скомпоновал инструкции по настройке среды в скрипт, который можно взять здесь: http://stupin.su/files/php_fpm_chroot.sh

Для удобства пересоздания chroot-среды предполагается, что файлы веб-приложения будут находиться в каталоге /site. Перед созданием chroot-среды из неё удаляются каталоги bin, etc, dev, lib, lib64, tmp, usr, var. Перед запуском скрипта нужно поменять его настройки под ваши нужды и обязательно убедиться в том, что переменная CHROOT указывает не на корень вашей системы. Чем это грозит, думаю говорить не приходится.

Внутри скрипта есть следующие настройки:
  • USER - пользователь, которому будут принадлежать файлы веб-приложения, лежащего в каталоге site,
  • GROUP - группа, которой будут принадлежать файлы веб-приложения, лежащего в каталоге site,
  • UID - идентификатор пользователя, указанного в USER,
  • GID - идентификатор группы, указанной в GROUP,
  • ZONEINFO - локальная временная зона веб-приложения, например - Asia/Yekaterinburg,
  • MAILER - программа-аналог sendmail для отправки писем. Доступны варианты - esmtp, msmtp. Любое другое значение отключит настройку программы (я в таких случаях указываю значение no),
  • MAIL_SERVER - адрес SMTP-сервера,
  • MAIL_PORT - порт SMTP-сервера (чаще всего это порт 25 или 587),
  • MAIL_USER - почтовый ящик с доменом. Предполагается, что аутентификация на SMTP-сервере происходит по имени этого почтового ящика, вместе с доменом,
  • MAIL_PASSWORD - пароль для аутентификации на SMTP-сервере.
На этом всё. Готов выслушать замечания и предложения.

Комментариев нет: