Купи доменное имя для своего блога, персональной web-странички или нового интернет проекта по выгодным ценам. Зарегистрировать домен в зоне .РФ или .RU за 195 руб.

PHP в темницу - Nginx + FastCGI + Jail

Цель: Нередко местом атак на сервер являются PHP-скрипты, SQL-инъекции и просто непродуманные конструкции и переменные в PHP-коде ведут к тому, что опытный злоумышленник получает контроль над вашим скриптом. А дальше дело техники, в считанные минуты можно узнать многе, от структуры папок и файлов, до файлов типа /etc/passwd. Скорее всего из PHP нельзя поднять привилегии до суперпользователя и снести систему, но снести скажем базу картинок, которые загружают ваши посетители через PHP можно.

У меня был случай, когда злоумышленник, на серваке раз в сутки запускался PHP-скрипт. Скрипт запускался кроном и имел привилегии суперпользователя. И однажды случился прецедент, в результате которого злоумышленник, получив доступ к php-скрипту сайта, поправил другой скрипт, именно тот, который запускался кроном. Таким образом, человек получил доступ к руту.

Так что во избежание подобных ситуаций следует принимать ряд мер, и одно из первых - chroot. Суть в том, что любому скрипту доступна на чтение файловая система, и это уже дыра в безопасности. Ведь умея читать - прочесть можно многое. Необходимо поместить PHP в темницу, где файловая система будет не реальная а своя.

Темницу мы создадим через инструмент Jail который я описывал ранее, далее перенесу туда PHP и запущу его оттуда как FastCGI. В качестве веб сервера я выбрал nginx, так как для него fastcgi - стандарт де факто.

Ставим и настраиваем Jail (темницу)

Все действия я произвожу в Gentoo Linux поэтому некоторые вещи специфичны именно для этой ОС, например установка пакетов я делаю командой emerge.

emerge -av jail
mkdir -p /jail/php
mkjailenv /jail/php
mkdir /jail/php/{bin,lib,proc}
addjailsw /jail/php
cp -d /lib/ld-*.so* /jail/php/lib/

Нашей новой системе нужен /proc

mount -t proc none /jail/php/proc/

Добавляем bash, куда же без него, хотя и необязательно

addjailsw /jail/php -P /bin/bash "-c exit"
ln -s bash /jail/php/bin/sh

Незнаю почему jail не сделал нам /dev/random но он нужен, php без него не захотел работать.

mknod /jail/php/dev/random  c  1 8

Создадим нового пользователя и группу - php, пускай все скрипты бегают из-под этого пользователя.

groupadd php
useradd -d /jail/php -s /usr/bin/jail -g php -G php php
chown root:php /jail/php
chmod 0750 /jail/php

Ставим PHP

Важно, php надо собрать с поддержкой CGI

USE="cgi" emerge php

И переносим его в темницу

addjailsw /jail/php -P /usr/bin/php-cgi "--version"
cp -r /usr/lib/php5 /jail/php/usr/lib/

Ставим Lighttpd

USE="-mysql -ssl -pcre fastcgi" emerge -v lighttpd

Нам нужет не сам Lighttpd а тулза, которая идёт вместе с ним — spawn-fcgi. У него много полезных фенек.

Запускаем PHP как FastCGI сервер

открываем конфиг, /etc/conf.d/spawn-fcgi

Правим строки:

USERID=php
GROUPID=php
SPAWNFCGI="/usr/bin/spawn/spawn-fcgi -c /jail/php"

Параметр “-с” указывает что надо сделать chroot в папку /jail/php

Если у нас fast-cgi сервер является локальный а не удалённый, то лучше перейти с TCP-сокетов на UNIX-сокеты. У меня это хорошо повысило производительность.

Для этого поправим

FCGIPORT="/var/run/spawn/spawn-fcgi.sock"

Сделаем папку для unix-socket`ов

mkdir /jail/php/var/run/spawn
chown root:php /jail/php/var/run/spawn
chmod 0770 /jail/php/var/run

Почемуто скрипты запуска достаночно скудные и не предусматривают, что могут использоваться unix-сокеты, поэтому подправим немного файл /etc/init.d/spwn-fcgi

там где запуск, вместо

"-p ${FCGIPORT}"
пишем
"-s ${FCGIPORT}"

Запускаем FastCGI демон

/etc/init.d/spwn-fcgi start

Устанавливаем Nginx

USE="fastcgi status -perl -imap" emerge -v nginx

Я посчитал, что perl мне ненужен, ведь я не пишу на нём, а imap прокси в nginx`е мне тоже не нужен, зато нужен fastcgi и собрать nginx нужно с поддержкой этого самого fastcgi.

Настраиваем Nginx

Правим файл /etc/nginx/nginx.conf

user php php;

location ~ \.php {
fastcgi_pass unix:/var/run/spawn/spawn-fcgi.sock;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME <PATH>/htdocs$fastcgi_script_name;
}

где <PATH> — путь до ваших файлов

Ещё кое что

Это конечно не всё, не стоит забывать что у PHP много модулей, например GD, а ведь поддержка этого модуля реализуется внешней unix-библиотекой. И её надо перенести в вашу темницу, всё это делается утилитой addjailsw. Так же не стоит набывать, например про mysql. Дело в том, что соединение между PHP и MySql у меня идёт через unix-сокеты и поэтому нам нужен доступ до /var/run/mysql. Возможно нам ещё чтонибудь пригодиться, например конект до memcached, поэтому мы смаунтим /var/run в /jail/php/var/run

mount --bind /var/run /jail/php/var/run

Конечно после перезагрузки сервера (не дай бог) надо заного перемаунтить /jail/php/proc и /jail/php/var/run , поэтому лучше их прописать в /etc/fstab

Запускаем Nginx

/etc/init.d/nginx start

Вот и всё

Попробуйте в PHP написать скрипт, который выведет список папок корня на экран. Что вы увидете? Увы для взломщика — он увидет дерево папки /jail/php и не более.

Регистрация доменов .РФ или RU за 195р!!!
Совместно с регистратором onreg.ru мы проводим акцию! Купи домен для своего блога или нового интернет проекта по выгодным ценам. Так домен в зоне .RU или .РФ стоит всего 195 рублей. При покупке нескольких доменов, возможны скидки. На onreg.ru есть система тикетов, через которую мы всегда готовы ответить на все ваши вопросы и предложения.
Комментарии
  • dehov — 12.09.2007 #1
    Все это хорошо, но для этих целей уже давно есть http://php-fpm.anight.org/
  • webphp — 07.09.2008 #2

    Jail будет работать с Apache ?

  • Костя — 19.02.2009 #3

    Если через FastCgi то конечно, проблем быть не должно

Оставить комментарий
Ваше имя:
E-mail:
Сайт (блог):
Сообщение:
Если вы не робот, введите код: