1

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

Я включил PHP в пользовательских каталогах, чтобы они могли экспериментировать с веб-сайтами и все с некоторым комфортом.

Недавно я понял, что весь код PHP в пользовательских каталогах выполняется пользователем веб-сервера (www-data), у которого есть некоторые привилегии, которые я, очевидно, не хочу давать пользователям. Уязвимый сайт или злоумышленник может удалить обычный веб-сайт сервера.

Есть ли способ запустить пользовательский PHP с правами пользователя?

Я подумал об обходном пути, который дает веб-серверу почти нулевые привилегии, поэтому его взлом не может поставить под угрозу что-либо серьезное. Это выполнимо в моей ситуации, так как веб-сайт очень очень прост (обычный HTML-индекс).

Сервер работает под управлением Debian Jessie с Apache 2.4.10.

1 ответ1

4

Я делал это несколько раз, используя nginx, lighttpd и apache. Концепция в основном одинакова во всех из них: [быстрые] процессы CGI, которые выполняются от имени пользователя.

Если вы хотите избавить себя от многих проблем, попробуйте поиграться с разрешениями, как предложили другие люди. В частности, если ваши пользовательские веб-сайты принадлежат пользователям, а ваш основной сайт принадлежит root или аналогичным, вы будете в приличной форме. Но пользователи по-прежнему не будут разделены и смогут читать файлы друг друга и т.д. (Пароли базы данных?). Запуск отдельных виртуальных серверов для каждого пользователя / сайта обеспечит вам максимальную безопасность, и это, безусловно, проще, чем пытаться отделить пользователей с помощью Apache.

Стандартный приемлемый способ разделения пользователей PHP в apache - через SuExec (есть также mpm-itk). Если вы используете Google для apache fastcgi suexec или аналогичного, вы должны получить множество результатов. Я думаю, что было бы нецелесообразно включать здесь полные указания. Он может варьироваться в зависимости от различных дизайнерских решений и используемого распределения. Вместо этого я постараюсь предоставить некоторые моменты, которые я считаю важными, и краткое описание моей конфигурации. Моя установка становится довольно сложной (и, кроме того, я запускаю собственный модуль SELinux). Вот [надеюсь] краткий обзор:

  • Виртуальные хосты на основе имени, указывая * .somedomain на сервер: user.somedomain - это имя виртуального хоста (я полагаю, вы могли бы сделать то же самое с пользовательскими каталогами?).
  • Один /etc/httpd/vhosts.d/user.conf для каждого пользователя.
  • Один каталог в /var/www/vhosts_config для каждого пользователя.
    • /var/www/vhosts_config/$USER/wrapper-bin содержит оболочку для выполнения PHP (подробнее об этом позже)
    • /var/www/vhosts_config/$USER/php/php.ini: мне нравится иметь отдельный php.ini каждого пользователя.
    • /var/www/vhosts_config/$USER/php/ext/*.ini: один INI-файл на каждое доступное расширение
    • /var/www/vhosts_config/$USER/php/ext-active/*.ini: символические ссылки обратно на ../ext для каждого включенного расширения (поэтому я могу также включать / отключать расширения для каждого пользователя)
  • /var/www/vhosts/user содержит фактический контент для vhost. Я рекомендую всегда использовать подкаталог public_html в качестве корня документа, чтобы у пользователей был каталог, который находится за пределами корня документа, для хранения файлов конфигурации и т.д.
  • Пользователи не должны иметь возможность читать файлы друг друга. Вам нужно разрешить веб-серверу +x на пользователях. Есть множество способов сделать это. Я использую POSIX ACL.

Конфигурация httpd для пользователя выглядит примерно так (для краткости изменена):

<VirtualHost *:80>
        ServerName someuser.somedomain
        DocumentRoot /var/www/vhosts/someuser/public_html

        SuexecUserGroup someuser someuser    

        FcgidWrapper /var/www/vhosts_config/someuser/wrapper-bin/php .php

        #max of 5 cgis per vhost
        FcgidMaxProcessesPerClass 5
        FcgidMinProcessesPerClass 0

        AddHandler php-fcgi .php
        Action php-fcgi /wrapper-bin/php

        Alias /wrapper-bin/ /var/www/vhosts_config/someuser/wrapper-bin/

        <Location /wrapper-bin/>
                Options +ExecCGI
                SetHandler fcgid-script
        </Location>
</VirtualHost>

suexec - это корневая программа setuid которая apache вызывает для запуска процессов от имени данного пользователя. Это довольно суетно. Требуется, чтобы выполняемая программа принадлежала пользователю и содержалась в подкаталоге каталога /var/www (это зависит от разных дистрибутивов Linux и устанавливается во время компиляции), который принадлежит пользователю. Вот почему каждому пользователю нужен свой скрипт PHP-оболочки.

/var/www/vhosts_config/someuser/wrapper-bin/php выглядит примерно так:

export PHPRC=/var/www/vhosts_config/someuser/php
export PHP_INI_SCAN_DIR=$PHPRC/ext-active/
export PHP_FCGI_CHILDREN=0
umask 0077
exec /usr/bin/php-cgi
  • PHP_INI_SCAN_DIR устанавливает каталог для поиска дополнительных файлов php.ini , которые я использую для загрузки специфичной для расширения конфигурации.
  • PHPRC перечисляет каталог, в котором можно найти файл php.ini .

Вам не нужно использовать отдельную конфигурацию PHP для каждого пользователя, и это, безусловно, усложняет ситуацию. Мне нравится давать пользователям урезанную конфигурацию и включать только то, что необходимо (и несколько распространенных расширений по умолчанию). Я также загружаю suhosion с различными конфигурациями для каждого пользователя (разные ключи шифрования).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .