apache и mod_ruid — исполнение скриптов от имени пользователя

При использовании mod_php все скрипты исполняются от имени веб-сервера (www-data, , etc), из-за чего довольно трудно определить чем занят тот или иной процесс и кто делает нагрузку.
Да, можно использовать suPHP, fastCGI и т.д. Но в таком случае можно забыть про выставление параметров в .htaccess, потеря производительности, невозможность использования mod_php и другие фишки.
Можно использовать peruser или mpm-itk. В первом случае будут плодиться процессы, каждый из которых будет кушать память, что не особо хорошо.
Во втором случае - нужно пересобирать апач.

Как же быть ?
Как вариант - использовать модуль mod_ruid2. Почему именно mod_ruid ? Одна из причин - модуль поддерживается и развивается. Последний коммит в svn сделан неделю назад (от даты данного поста), это вселяет определенную надежду, что модуль и дальше будет развиваться, а найденные баги будут исправляться. mod_ruid не требует пересборки ни apache ни чего либо еще, будут нормально работать акселераторы (eAccelerator, xcache).

Гугл привел на форум, где описан этот модуль и как его ставить.
В кратце - собирается модуль mod_ruid, с помощью которого каждый вирт. хост будет работать под именем своего владельца. Это снимает проблему выставления прав 777, файлы и каталоги будут создаваться с тем же владельцем, которому принадлежит аккаунт.
При автообновлении из админки разного рода Joomla!, WordPress и т.д. больше не будут ругаться на невозможность создать каталог или файл.
Значительно повышается безопасность - можно выставить на каталоги права 750 и 640 на файлы, что исключит возможность доступа пользователей к чужим данным.
Стоит заметить, что производительность немного упадет, но все же это будет быстрее чем при использовании suPHP/CGI.

Ставим mod_ruid на сервер виртуального хостинга под управлением панели .
Для сборки модуля необходима библиотека libcap.

# yum install libcap-devel  # RHEL

или

# aptitude install libcap2-dev  # debian

Качаем исходники модуля и собираем

# cd /usr/local/directadmin/custombuild
# wget http://garr.dl.sourceforge.net/project/mod-ruid/mod_ruid2/mod_ruid2-0.9.tar.bz2
# tar xvf mod_ruid2-0.9.tar.bz2
# cd mod_ruid2-0.9/

Читаем README и собираем модуль

# apxs -a -i -l cap -c mod_ruid2.c

Модуль будет собран, проинсталирован и в httpd.conf будет добавлена строка

LoadModule ruid2_module       /usr/lib/apache/mod_ruid2.so

Теперь необходимо изменить httpd.conf. Открываем /etc/httpd/conf/httpd.conf, находим строки
User apache
Group apache

и добавляем ниже следующие директивы:

RMode config
RUidGid apache apache
RGroups apache

Копируем шаблоны виртуального хоста:

# cd /usr/local/directadmin/data/templates
# cp virtual_host2* custom/
# cd custom

Открываем шаблон и после |USECANONICALNAME| добавляем следующие директивы:

	# SuexecUserGroup |USER| |GROUP|
	RMode config
	RUidGid |USER| |GROUP|
	RGroups apache

Строку с SuexecUserGroup необходимо закоментировать.

Чтобы пользователи могли нормально работать с phpmyadmin / webmail добавим описание директорий с указанием владельца webapps:

        <location /phpMyAdmin>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>
        <location /phpmyadmin>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>
        <location /squirrelmail>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>
        <location /roundcube>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>
        <location /webmail>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>
        <location /atmail>
           RMode config
           RUidGid webapps webapps
           RGroups apache
        </location>

Эти изменения нужно сделать во всех 4-х шаблонах. После чего, пересоздаем httpd.conf виртуальных хостов:

# echo "action=rewrite&value=httpd" >> /usr/local/directadmin/data/task.queue
# /usr/local/directadmin/dataskq d800

Проверяем синтаксис конфигурации apache, если все нормально - рестартуем веб-сервер:

# apachectl configtest
Syntax OK
# /etc/init.d/httpd restart
Stopping httpd:
Remaining processes: 16003 16118 32155
Stopping httpd: OK
Starting httpd: OK

Смотрим 'top' и видим какой пользователь сколько и чего потребляет.

top - 15:03:17 up 76 days,  1:12,  1 user,  load average: 0.19, 0.43, 0.38
Tasks:  68 total,   1 running,  67 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3%us,  0.0%sy,  0.0%ni, 98.3%id,  1.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    906284k total,   708884k used,   197400k free,   145488k buffers
Swap:  2097144k total,      756k used,  2096388k free,   398276k cached
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
21785 adminco   16   0  162m  42m  26m S   43  4.1   0:14.56 httpd
 4029 adminco   15   0  161m 113m  99m S   31 11.1   4:55.01 httpd
23944 adminco   15   0  161m  29m  12m R   24  2.8   0:01.86 httpd
30611 mysql     15   0  173m 137m 6056 S    8 13.5   7:32.19 mysqld
 7313 adminco   15   0  163m 106m  90m S    5 10.4   4:46.85 httpd
23954 apache    15   0  155m  22m  10m S    4  2.2   0:00.09 httpd
13837 apache    10  -5 64032 6920 1844 S    1  0.7   1:39.20 nginx

В приложенном файле [1] уже готовые шаблоны для DirectAdmin.
В шаблонах исправлена ошибка DirectAdmin, из-за которой виртуальный хост не мог использовать несколько IP адресов (актуально для версии 1.36).

PS. Забыл написать, что необходимо запретить использование функции dl() в php.ini.
А еще желательно восстановить владельца файлов/каталогов в public_hml
Можно так:

# cd /usr/local/directadmin/scripts ; ./set_permissions.sh user_homes
# find /home/*/domains/*/public_html -type d -print0 | xargs -0 chmod 711
# find /home/*/domains/*/public_html -type f -print0 | xargs -0 chmod 644
# cd /usr/local/directadmin/data/users
# for i in `ls`; do { chown -R $i:$i /home/$i/domains/*/public_html;}; done;

Если используются perl-скрипты, то этим файлам также надо поправить права:

find /home/. -type f -name '*.cgi*' -exec chmod 755 {} \; find /home/. -type f -name '*.pl*' -exec chmod 755 {} \; find /home/. -type f -name '*.pm*' -exec chmod 755 {} \;

Спасибо Алексею за его замечание.

Upd: Забыл написать, что еще потребуется восстановить права для каталога /var/www/html, где лежит phpmyadmin и разные вебмаил-ы:

# chown -R webapps:webapps /var/www/html/
# find /var/www/html -type f -print0 | xargs -0 chmod 644
# find /var/www/html -type d -print0 | xargs -0 chmod 711

[1] Файл шаблонов виртуальных хостов

Any comments ? 🙂

47 comments on “apache и mod_ruid — исполнение скриптов от имени пользователя

  1. не просто блог. а супер блог. сделал как написано и доволен. Теперь реально видно кто грузит систему…

  2. По отношению с mpm-itk какие есть плюшки, а какие минусы кроме пересборки апача, который делается в два клика.

  3. Хм. Модуль работает быстрее и потребляет меньше памяти чем ядро mpm? Вы проводили замеры?

  4. Лично тесты не проводил, но начитавшись разного (в том числе на том же серче), ставить эксперименты не очень хотелось на рабочем тазике.
    Моей задачей было сделать возможным видеть кем занят апач и при этом без глобальных пересборок и изменений в конфигах, а также чтобы в дальнейшем было не очень сложно сопровождать.
    Поэтому выбор пал именно на mod_ruid2.

    Что касается тестирования, то вот тут
    http://blog.stuartherbert.com/php/2008/04/19/using-mpm-itk-to-secure-a-shared-server/
    есть немного инфы.
    Цитата оттуда:

    To benchmark mpm-itk, I used Apache s ab benchmark to load a simple
    phpinfo() page 1,000 times. I ran the benchmark five times, and averaged
    the results.
    mpm-itk: average of 37.01 seconds
    mpm-prefork: average of 6.21 seconds
    

    Там же есть сравнение с suphp, suexec и mpm-peruser

    PS. согласен, что ruid2 не идеальный вариант, тем не менее это немного лучше, чем suexec или suphp.

    Насчет пересборки апача двумя кликами.
    В ispmanager-e он ставиться из репы, да.
    У клиента все вертится под Directadmin-ом и там двумя кликами не получится 🙂

  5. Посмотрел, таки да, нужно добавить пару строк как в ips_virtual_host.conf, так и в redirect_virtual_host.conf

    Копируем эти файлы шаблонов в templates/custom/
    комментируем строку SuexecUserGroup |USER| |GROUP|
    и ниже надо добавить эти строки:
    RMode config
    RUidGid |USER| |GROUP|
    RGroups apache

    Алексей, спасибо за наводку.

    🙂

  6. Я сначала выполнил все, как написано в статье. Выполнил echo «action=rewrite&value=httpd» >> /usr/local/directadmin/data/task.queue — Все встало ровно и без багов.
    Добавил в кастом эти два шаблона. закомментил строки SuexecUserGroup |USER| |GROUP| и добавил RMode config
    RUidGid |USER| |GROUP|
    RGroups apache

    потом решил еще раз прогнать echo «action=rewrite&value=httpd» >> /usr/local/directadmin/data/task.queue и заругался скрипт что-то. типа нет или не такие как надо (уже не помню). ну все так и стоит. вроде показывает нагрузку юзеров)
    в целом — хочу поблагодарить, за статьи, великодушно. все прямо для нубов расписано.

  7. в custom нужно добвлять не два, а 6 шаблонов:
    virtual_host2* (если apache2)
    и ips_virtual_host.conf, redirect_virtual_host.conf

    А вот ошибки надо исправлять.
    Показывайте, что за ошибки.

  8. Сейчас еще раз закинул те 4 шаблона что прикреплены к статье. и еще раз скопировал и подправил 2 (ips_virtual_host.conf, redirect_virtual_host.conf)

    и вроде все как по-маслу))

    server:/usr/local/directadmin/data/templates/custom# echo «action=rewrite&value=httpd» >> /usr/local/directadmin/data/task.queue
    server:/usr/local/directadmin/data/templates/custom# /usr/local/directadmin/dataskq d800
    In debug mode
    Debug set to level 800
    root priv set: uid:0 gid:0 euid:0 egid:0
    pidfile written
    staring queue
    done queue
    server:/usr/local/directadmin/data/templates/custom# apachectl configtest
    Syntax OK
    server:/usr/local/directadmin/data/templates/custom# /etc/init.d/httpd restart
    Stopping httpd:
    Remaining processes: 14643 14657 14810 14961 14966 14968
    Stopping httpd:
    Starting httpd: OK
    server:/usr/local/directadmin/data/templates/custom#

    Возник вопрос такого плана — раньше юзал аккаунты на IP адресах (без доменов) типа http://31.31.31.31/~myftp/ в public_html кидал htaccess с текстом Options +Indexes
    и отображалось содержимое.
    Сейчас отправляет в forbidden. Но видимо из-за прав.
    Точно. поправил public_html с 711 на 755 и содержимое вновь отображается:)
    Еще раз спасибо!

  9. еще забыли про perl ), им же нужен 755
    find /home/. -type f -name ‘*.cgi*’ -exec chmod 755 {} \;
    find /home/. -type f -name ‘*.pl*’ -exec chmod 755 {} \;
    find /home/. -type f -name ‘*.pm*’ -exec chmod 755 {} \;

  10. # find /home/*/domains/*/public_html -type d -print0 | xargs -0 chmod 711
    # find /home/*/domains/*/public_html -type f -print0 | xargs -0 chmod 644

    а разве не лучше права сделать
    700 и 600 соответственно?

    • Иногда лучше, но не всегда.

      у меня, например, nginx (который работает от имени www-data) занимается раздачей статики, и ему нужны права на вход в каталог юзера и чтение этих статичных файлов.
      Вот поэтому права 644 и 711.

      Если нет схемы frontend<>backend, тогда 600 и 700 более приемлемы.

  11. Во-первых, спасибо за полезную статью! Настроил сервер с приличным кол-вом виртуальных хостов (больше 500) — все работает как часики.

    Попутно прошу помощи на счет последней дырки в exim.
    Я только заметил, что его нужно срочно обновить. Но никак не пойму как это сделать в directadmin. Подскажите пожалуйста! Если не трудно список всех команд — я с DA пока что на Вы.

  12. Спасибо за совет на счет модулей. Действительно не хватало libperl5.10. А я думал, что делаю неправильно.

    Вообще странный подход. Чтобы залатать опасную дырку приходится лазить по форумам. И никакой автоматизации.

    • Почему нет ? Есть — используйте custombuild 1.2.xx вместо 1.1
      ну или — «позвать админа» 🙂

      Ну а форумы для того и нужны, что бы по ним ходить и просвещаться.

      • Этот скрипт нужен только для обновления софта, который был им же и установлен. В данном случае бета или нет — особо значения не имеет.
        Напомню, что в ДА создание бакапов/перенос пользователей (админ-уровень) тоже до сих пор является «бета», тем не менее используется эта фича.
        Главное с умом использовать 🙂

  13. Кстати, для подписчиков на данную тему — пару дней назад обновился архив mod_ruid2
    Желающие могут проапдейтить версию модуля.

      • Похоже на worker толку нет, сделал по ману, но в топе все равно все процесы от имени Apache

        • Это , можно сказать, нормально.
          Попробуйте скриптом создать файл — сразу будет видно есть толк или нет (я про владельца созданного файла, должен быть владелец аккаунта, а не апач).

        • Так можно узнать от какого пользователя исполняются скрипты:
          var_export(posix_getpwuid(posix_getuid()));

  14. А как его снести? Прообовал просто закоментить все строки в которые вносил изменения, Апач запустился и ошибок не выдал но сайты открывать отказался, ошибка «Permission denied» не хватает прав…

    chmod не трогал после установки Ruid2, стоит исходный 755, 644 итд как и до установки

    • «ошибка «Permission denied» не хватает прав» — так и должно быть. Апач пытается работать от пользователя apache, который не имеет прав на чтение в папки пользователей.

      Отключайте в конфиге модуль mod_ruid2:
      #LoadModule ruid2_module /path/to/mod_ruid2.so

      • Вроде коментил mod_ruid2:.. но чето не особо 🙂

        Решил оставить, вроде и не мешает тоже. Только сразу говорю, кто может столкнеться как в моем случаи. Если апач работает как mpm -worker толку от mod_ruid нет. Он видимо только под perfork расчитан

        • Алекс, Вам на форуме ДА так и ответили, что mod_ruid2 расчитан на apache prefork.

          Но все равно спасибо Вам за тест.

  15. Убрать загрузку модуля из конфига апачи.
    apachectl configtest — покажет есть ошибка в конфигурации или нет.

    «Permission denied» — куда ? и кто пишет ?
    Проверить доступ и владельца к логам /var/log/httpd/

  16. Еще интересен момент, а на производитеность mod_ruid оказывает влияние? Если кто вкурсе или тестил отпишитесь, спс

    • По моим скромным тестам при использовании mod_ruid2, производительность падает, но в пределах допустимого. Этот небольшой % потери производительности стоит того.

  17. А если у меня голый апач и пхп безовсяких панелей что и где нужно добавить кроме /etc/httpd/conf/httpd.conf ?

    Точнее мне не понятно где именно нужно поменять это?
    # SuexecUserGroup |USER| |GROUP|
    RMode config
    RUidGid |USER| |GROUP|
    RGroups apache

  18. (Забыл упомянуть что стоит nginx)

    Так же не понятно какие права выставлять на папку сайта если у меня сайт лежит тут /home/username/html/
    логи тут /home/username/logs/

    Если я сделаю так: chown -R username:apache /home/username
    или как правильно?

  19. владельца оставить только как «username»
    Права на каталоги: 0750
    на файлы 0640

    т.к. процесс апача будет выполняться под юзером, то он нормально получит доступ к файлам юзера и нет наобности отдельно выставлять владельца для апача.

    в конфиге вирт.хоста в строке:
    RUidGid |USER| |GROUP|

    |USER| |GROUP| — заменить на соответствующего юзера и его группу

1 Отклики /Обратные ссылки для "apache и mod_ruid — исполнение скриптов от имени пользователя"

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*