Мар 17

При размещении большого числа проектов на одном сервере появляется угроза, что при взломе одного из хостов нехороший человек получит доступ и к соседним проектам. Или же, если вы хостите чужие проекты и предоставляете кому-то другому доступ к серверу, очень хорошо бы было исключить возможность доступа к другим хостам. Дальше предлагается однин из многих вариантов решения этой проблемы.

Установка php-fpm.
Php-fpm официально включен в php начиная с версии 5.3.3, в первую очередь скорее всего вам нужно обновить php.
Debian Squeeze:
в /etc/apt/sources.list добавте

deb http://packages.dotdeb.org squeeze all

Дальше нужно поставить ключ:

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | apt-key add -

Теперь ставим пакеты:

aptitude update
aptitude install php5 php5-cli php5-mysql php5-fpm

Ubuntu 10.04:
PHP 5.3.5 можно взять с ppa https://launchpad.net/~nginx/+archive/php5
в /etc/apt/sources.list добавте

deb http://ppa.launchpad.net/nginx/php5/ubuntu lucid main
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
sudo aptitude update
sudo aptitude install php5 php5-cli php5-mysql php5-fpm

Пулы php-fpm
Пулы позволяют задать разные настройки для отдельных хостов. Разные php.ini, количество дочерних процессов fpm’a, пользователя/группу запускаемых процессов etc.
Идем в /etc/php5/fpm/, открываем main.conf и добавляем туда:

include=/etc/php5/fpm/pool.d/*.conf

Теперь перейдем в директорию /etc/php5/fpm/pool.d/ и создадим конфиги для виртуальных хостов.
Для хостов, которые будут работать через апач сокет должен находиться в /var/lib/apache2/fastcgi/

# vi one-example-com.conf
[one-example-com]
listen = /var/run/one-example-com-php5-fpm.sock
user = one-example-com
group = one-example-com
pm = dynamic
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 15
pm.max_requests = 200

listen.owner = root
listen.group = www-data
listen.mode = 0660

и второй:

# vi two-example-com.conf
[two-example-com]
listen = /var/run/two-example-com-php5-fpm.sock
user = two-example-com
group = two-example-com
pm = dynamic
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 15
pm.max_requests = 200

listen.owner = root
listen.group = www-data
listen.mode = 0660

Добавим юзеров в систему:

useradd one-example-com
useradd two-example-com

Теперь, что б apache/nginx смог отдавать статику юзера www-data нужно добавить в группы созданных пользователей.

#vi /etc/group
...
one-example-com:x:1028:www-data
two-example-com:x:1029:www-data

Все, перезапускаем php-fpm

/etc/init.d/php5-fpm restart

Apache
Apache умеет работать с fastcgi через сторонний модуль mod-fastcgi, поставим его.

aptitude install libapache2-mod-fastcgi
cd /etc/apache2/mods-available/
a2enmod fastcgi
# vi /etc/apache2/mods-enabled/fastcgi.conf
<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .fcgi
  #FastCgiWrapper /usr/lib/apache2/suexec
  FastCgiIpcDir /var/lib/apache2/fastcgi
  AddHandler php-fcgi .php .php5
    <FilesMatch \.php$>
        SetHandler php5-fcgi
  </FilesMatch>
  <Location "/fastcgiphp">
        Order Deny,Allow
        Deny from All
        # Prevent accessing this path directly
        Allow from env=REDIRECT_STATUS
  </Location>
Action php5-fcgi /fastcgiphp
Action php5-fastcgi /fastcgiphp
</IfModule>

Теперь идем в /etc/apache2/sites-available/ и создадим конфиги для наших хостов:

# vi one.example.com

<VirtualHost *:80>

        ServerName one.example.com
        ServerAlias www.one.example.com
        ServerAdmin admin@example.com
        DocumentRoot /var/www/one.example.com/public
        Options -Indexes

        
        <Directory /var/www/one.example.com/public>
                Order Allow,Deny
                Allow from all
        </Directory>

<IfModule mod_fastcgi.c>
        FastCgiExternalServer /usr/local/bin/one-example-com-fpm -socket one-example-com-php5-fpm.sock

        Alias /fastcgiphp /usr/local/bin/one-example-com-fpm
</IfModule>


CustomLog /var/log/apache2/one.example.com/access.log combined
ErrorLog /var/log/apache2/one.example.com/error.log

</VirtualHost>
# vi two.example.com

<VirtualHost *:80>

        ServerName two.example.com
        ServerAlias www.two.example.com
        ServerAdmin admin@example.com
        DocumentRoot /var/www/two.example.com/public
        Options -Indexes

        
        <Directory /var/www/two.example.com/public>
                Order Allow,Deny
                Allow from all
        </Directory>

<IfModule mod_fastcgi.c>
        FastCgiExternalServer /usr/local/bin/two-example-com-fpm -socket two-example-com-php5-fpm.sock

        Alias /fastcgiphp /usr/local/bin/two-example-com-fpm
</IfModule>

CustomLog /var/log/apache2/two.example.com/access.log combined
ErrorLog /var/log/apache2/two.example.com/error.log

</VirtualHost>

Файлы /usr/local/bin/*-fpm не должны существовать в реальности на файловой системе и должны быть уникальны для каждого виртуального хоста, указанные в конфиге сокеты должны находиться в /var/lib/apache2/fastcgi/

a2ensite one.example.com
a2ensite two.example.com

Создадим нужные директории/файлы, настроим права:

mkdir -p /var/www/one.example.com/public/
mkdir -p /var/www/two.example.com/public/
echo '<?php echo "one.example.com"; ?>' > /var/www/one.example.com/public/index.php
echo '<?php echo "two.example.com"; ?>' > /var/www/two.example.com/public/index.php
chown -R one-example-com /var/www/one.example.com/public/
chown -R two-example-com /var/www/two.example.com/public/
chmod 750 /var/www/*

И перезапустим apache:

/etc/init.d/apache2 restart

Все, теперь можете проверить работоспособность хостов. Еще рекомендую залить веб-шелл и проверить правильно ли все настроено. Т.е. с веб шелла войти в директорию другого хоста будет нельзя. Скачать веб шелл можно тут

Nginx
С nginx’ом все в разы проще, начнем. Переходим в /etc/nginx/ и открываем конфиг nginx.conf

# vi nginx.conf
...
http {
...
include /etc/nginx/vhost/*;
...

Создаем директорию vhost и конфиги для хостов:

# mkdir vhost
# vi vhost/one.example.com
server {
        listen ип_сервера:80;
        server_name one.example.com;
        client_max_body_size 5M;
        root /var/www/one.example.com/www/public;
        access_log     /var/log/nginx/one.example.com/access.log;
        error_log       /var/log/nginx/one.example.com/error.log;

        location / {
                index index.php index.html;
        }

        location ~ \.php$ {
                fastcgi_pass    unix:/var/run/one-example-com-php5-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /var/www/one.example.com/www/public$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_param  QUERY_STRING     $uri;
                include        fastcgi_params;
        }
}
# vi vhost/two.example.com
server {
        listen ип_сервера:80;
        server_name two.example.com;
        client_max_body_size 5M;
        root /var/www/two.example.com/www/public;
        access_log     /var/log/nginx/two.example.com/access.log;
        error_log       /var/log/nginx/two.example.com/error.log;

        location / {
                index index.php index.html;
        }

        location ~ \.php$ {
                fastcgi_pass    unix:/var/run/two-example-com-php5-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /var/www/two.example.com/www/public$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_param  QUERY_STRING     $uri;
                include        fastcgi_params;
        }
}
/etc/init.d/nginx restart

Все, теперь создаем нужные директории, правим права. Все так же, как описано в части про apache. После проверяем тем же веб шеллом.

11 Responses to “Изоляция виртуальных хостов с использованием nginx/apache + fastcgi + пулы php-fpm”

  1. Chaser Says:

    Добавить юзеров можно следующей командой:
    usermod -a -G www-data user_name
    что поможет при автоматизации разворачивания хостинга

  2. Free Says:

    если вы добавляете пользователя www-data в группы пользователей владельцев файлов вхоста — то где изоляция сайтов?

    если вскрыли вхост1 то через www-data можно получить доступ в вхост2

  3. jeka Says:

    Финт с www-data нужен nginx’у для доступа к статике, он не умеет работать от разных юзеров, тут главное что б не было ни одного хоста, работающего от www-data(именно скрипты). С него можно будет получить доступ к остальным. А просто присутствие в групе www-data не позволит получить доступ к остальным хостам, скрипты исполняются через отдельного юзера.

  4. Free Says:

    т.е. я на все .php файлы в vhost’e могу поставить

    chmod 750 *.php
    chown vhostuser1:vhostuser1 *.php

    и все будет работать?

  5. Free Says:

    сейчас проверил, да действительно, можно даже поставить chmod 700 *.php — все прекрасно работает.

  6. Free Says:

    еще такой вопрос, например, для пула не установлен open_basedir.
    php скрипт может создать новый файл в папке любого vhost’a.

    как от этого можно защититься?

  7. Free Says:

    игнорируйте мой предыдущий пост, ничего не копируется. Permission denied.

    Кстати, неплохо было бы добавить в конфиги пулов директивы open_basedir, disable_functions и safe_mode.

  8. jeka Says:

    Да, disable_functions стоило б добавить, допишу как-то. С open_basedir и safe_mode на практике бывает куча проблем и когда на сервере много хостов как правило разбираться и фиксить это времени нет.
    Еще что таки стоит добавить, это разделение директорий для сессий и временных файлов(upload_tmp_dir и session.save_path) для каждого хоста. Только важно после этого не забыть поправить скрипт очистки старых сессий(см. /etc/cron.d/php5), а то годика так через два свободные иноды на фс могут кончиться.

  9. karavan Says:

    Я бы еще рекомендовал каждый пул снабдить опцией chrootdir.

  10. TimothyHig Says:

    I found your blog web site on google and check a couple of of your early posts. Proceed to keep up the very good operate. I simply extra up your RSS feed to my MSN Information Reader. Seeking ahead to studying more from you afterward!… http://hellowh983mm.com

  11. grummiet Says:

    Советую Вам посетить сайт, на котором есть много статей на интересующую Вас тему.


    философски так… fifa 15 скачать торрент repack механики, кряк фифа 15 или фифа 16 официальный сайт fifa 15 полная версия скачать торрент

Написать ответ