php-fpm и open_basedir

Когда-то здесь была статья о том, как можно малой кровью сделать полноценную поддержку open_basedir на сервере с nginx и php-fpm. Метод заключался в предварительном запуске специального скрипта security.php, самостоятельно определяющего open_basedir и последующей передаче управления пользовательскому сценарию. С тех пор много воды утекло, и статья успела полностью потерять актуальность.

Если вам нужна полноценная поддержка open_basedir в указанной конфигурации, вы можете сделать несколько пулов рабочих процессов, указав каждому пулу опцию «pm = ondemand». Это сведёт на нет накладные расходы, которые имели место в конфигурации с несколькими пулами ранее. Наконец, можно держать один пул, но в php.ini завести несколько секций следующего вида

[HOST=server1.ru]
open_basedir = /some/path1:/tmp:/usr/share/php

[HOST=server2.co.id]
open_basedir = /some/path2:/tmp:/usr/share/php

14 комментариев: php-fpm и open_basedir

  1. WST говорит:

    Кстати, нужно сказать, что disable_functions всё-таки не срабатывает. Тем не менее, переопределить open_basedir при помощи ini_set в пользовательском коде уже не удаётся… Странное поведение. Скорее всего, ini_set для одной и той же конфигурационной директивы может быть выполнен только единожды, что, однако, не отражено в документации: http://ru.php.net/ini_set

    • Андрей говорит:

      WST, Отражено. Там сказано что если open_basedir уже был установлен, то ini_set может быть установлен только внутри уже существующей настройки. Т.е. сужен, но никак не расширен

      > test, ini_set для параметра open_basedir прокатывает только один раз, то есть если задать его в первом обрабатываемом скрипте, то в скрипте пользователя изменить это значение уже не получится. Мне не известно, является ли это стандартным поведением, но я просто пользуюсь этим и делюсь.

      • Илья Аверков говорит:

        В любом случае, в наши дни это уже неактуально, так как теперь есть возможность создавать несколько пулов (с разными open_basedir) и выбирать управление процессами dynamic

  2. Avari говорит:

    По памяти: не всякую переменную из php.ini можно (пере)определить, скажем, в апачевском конфиге vhost’а через php_admin_value. Здесь должно быть то же самое.
    Немножко поиска…
    …For example, some settings may be set within a PHP script using ini_set(), whereas others may require php.ini or httpd.conf.
    disable_functions: php.ini only
    В общем, это ограничение php.
    Ничего особо страшного… но фишка php-fpm c запуском от имени разных пользователей и с разными php.ini по-прежнему вне конкуренции.

  3. WST говорит:

    У каждого подхода свой недостаток. Конкуренция у Вашего способа серьёзная, хотя бы потому что nginx в паре с php-fpm чаще всего ставят как легковесную альтернативу Apache на слабых VPS, а на слабых VPS остро стоит проблема использования ОЗУ. Если делать на каждого пользователя свой пул воркеров, ресурсы такой системы будут быстро исчерпаны.

  4. WST говорит:

    По крайней мере, open_basedir задаётся успешно. Возможно, именно по той причине, что он не определён ни в php.ini, ни в php-fpm.xml.

  5. Артем говорит:

    location ~* \.php$
    {
    fastcgi_pass unix:/tmp/fastcgi.socket;
    fastcgi_index index.php;
    fastcgi_param DOCUMENT_ROOT /hc45.ru;
    fastcgi_param SCRIPT_FILENAME /securityhandler.php;
    fastcgi_param USER_SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    include /usr/local/etc/nginx/fastcgi_params;

    Не подскажете куда копнуть ?

    FastCGI sent in stderr: «PHP Notice: Undefined index: USER_SCRIPT_FILENAME in /securityhandler.php on line 19″

  6. Артем говорит:

    php.ini, как оказалось, успешно справляется вот с таким:

    [HOST=hostname]
    open_basedir = somedir

    мне кажется, элегантнее будет.

  7. test говорит:

    я не могу понять если вы используете

    ini_set(‘open_basedir’, ‘/home/’ . $username . ‘:/tmp:/opt/nginx/html/errors’);

    значит в скрипте МОЖНО поставить open_basedir? Если мне надо для одного сайта сделать, я могу просто в php.ini ее выставить, это будет работать, или мне надо вверху каждого скрипта сайта прописывать

    ini_set(‘open_basedir’, ‘/home/’)

  8. WST говорит:

    test, ini_set для параметра open_basedir прокатывает только один раз, то есть если задать его в первом обрабатываемом скрипте, то в скрипте пользователя изменить это значение уже не получится. Мне не известно, является ли это стандартным поведением, но я просто пользуюсь этим и делюсь.

    Артём, выглядит действительно много элегантнее, попробую — отпишусь. Особенно интересно по той причине, что я с товарищами в скором будущем заведу коммерческий хостинг с nginx.

    P.S: недавно публиковал небольшое обновление по ссылке на источник

  9. test говорит:

    Ну что там, в php.ini корректно у вас все работает, затестируйте уже, тут весь рунет ждет :)

  10. WST говорит:

    test, да, работает. Как давно ввели эту штуку? Имеет смысл воспользоваться ею…
    P.S.: рунет бы лучше сам затестил вместо того, чтобы ждать лентяя :)

  11. test говорит:

    Добавлю немного. Если ставить байсдир в php.ini это распространяется в том числе и на скрипты, которые запускаются с командной строки, то есть вы будете везде приввязаны к одному байс диру. Как вариант можно просто во всех своих скриптах инклудить один скрипт, который будет

    ini_set(‘open_basedir’ …

    ставить.

  12. WST говорит:

    test, речь об указании open_basedir в специальной секции вида [HOST=…]. Опции в этой секции, по всей видимости, применяются только к запросам в рамках данного хоста. Что такое хост определить для командной строки затруднительно, поэтому вряд ли эти секции влияют на работу скриптов для командной строки. По крайней мере, мои скрипты (обновляющие RRD-базы итп) остались работоспособными после того как я добавил одну такую секцию…

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>