Перейти к содержимому

Open basedir что это

  • автор:

Загрузка файлов и open_basedir: почему надо пользоваться стандартными функциями

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

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

  • open_basedir ограничивает список файлов, к которым может обращаться PHP, указанным деревом директорий.
  • open_basedir может применяться независимо от того, используется защищенный режим или нет.

Конечно же язык PHP разрабатывают неглупые люди, поэтому действие open_basedir не распространяется на функции is_uploaded_file и move_uploaded_file, которые, собственно, и предназначены для работы с загруженными файлами.

Так в чём же тогда проблема? А проблема вот в чём: многие (действительно многие!) обращаются к загруженным файлам именно напрямую, в обход стандартных функций.

Обычно это делается в тех случаях, когда загруженный файл не предполагается хранить на сайте. Как правило это импорт прайс-листов (csv, xls), картинки, которые конвертируются перед сохранением в дереве файлов сайта. Часто $_FILES используется для проверки загруженной картинки (getimagesize) перед вызовом move_uploded_file.

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

P. S. Кто-то может сказать «нефиг так конфигурировать сервера, что скрипты перестают работать». Однако я считаю, что если настройка есть, то кто-нибудь её обязательно использует. И если ваша программа после этого перестанет работать, то камни полетят в вас. Оно вам (нам) надо?

  • php
  • upload
  • загрузка файлов
  • open_basedir
  • move_uploaded_file
  • is_uploaded_file

Для чего нужна и как использовать open_basedir

Директива open_basedir указывается в конфигурационном файле PHP (php.ini) и устанавливает директории, к которым может иметь доступ PHP. Под доступом понимаются любые действия с файлами: открытие (например, функции fopen() или gzopen()), записи и выполнения. Если директива open_basedir установлена и делается попытка запустить файл, который находится за пределами перечисленных директорий, то скрипт не запустится и выдаст ошибку:

[Wed Apr 1 13:11:34 2020] PHP Warning: Unknown: open_basedir restriction in effect. File(/usr/share/seeker/template/nearyou/php/info.php) is not within the allowed path(s): (/srv/http/:/etc/webapps/:/usr/share/webapps/:/tmp/:/home/mial/) in Unknown on line 0

Пример значения open_basedir:

open_basedir = /srv/http/:/etc/webapps/:/usr/share/webapps/:/tmp/:/home/mial/

В указанном примере разрешён запуск скриптов PHP, а также операции с файлами в директориях:

  • /srv/http/
  • /etc/webapps/
  • /usr/share/webapps/
  • /tmp/
  • /home/mial/

Директива open_basedir оказывает влияние на многие функции. Больше всего в ней смысла при использовании на уровне конфигурационных файлов веб-сервера на уровне директорий или виртуальных хостов.

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

Опция open_basedir может распространяться не только на функции для работы с файловой системой; например, если MySQL настроен использовать драйвер mysqlnd, то LOAD DATA INFILE подпадает под опцию open_basedir . Множество функций PHP также использует open_basedir.

Специальное значение . (точка) обозначает, что рабочая директория скрипта будет использована в качестве базовой директории. Однако, это немного опасно, так как текущая директория скрипта может быть легко изменена с помощью chdir().

В httpd.conf, open_basedir может быть выключена (например, для некоторых виртуальных хостов) тем же способом, что и любая другая конфигурационная директива:

php_admin_value open_basedir none

В Windows разделяйте директории символом ; (точкой с запятой). На всех остальных системах, разделяйте директории символом : (двоеточием). При работе в качестве модуля Apache, пути open_basedir автоматически наследуются от родительских директорий.

Связанные статьи:

  • Что делать если PHP скрипту не хватает времени и памяти. Почему большой файл не загружается на сайт или в phpMyAdmin (100%)
  • Почему не работают короткие теги в PHP (100%)
  • Как изменить количество цифр после запятой в PHP. Как увеличить точность вычислений в PHP (100%)
  • Как и какие функции отключить в PHP (100%)
  • Как установить веб-сервер Apache с PHP, MySQL и phpMyAdmin на Windows (100%)
  • Как сбросить пароль root MySQL или MariaDB в Windows (RANDOM — 50%)

Нужен хостинг с защитой от шелов и прочего

>> Как сказал smart2web только через open_basedir. Я не буду с Вами спорить, но open_basedir абсолютно бесполезная штука, не кто не мешает вызвать любую функцию из семейства exec и запустить отдельный процесс без open_basedir, при этом не обязательно на php. Можно запретить половину функций, но часть CMS при этом точно перестанет работать.

— С Уважением Алексей Маникин.
На сайте с 30.12.2015
24 марта 2017, 13:02

alexeyymanikin:
>> Как сказал smart2web только через open_basedir.

Я не буду с Вами спорить, но open_basedir абсолютно бесполезная штука, не кто не мешает вызвать любую функцию из семейства exec и запустить отдельный процесс без open_basedir, при этом не обязательно на php.

Можно запретить половину функций, но часть CMS при этом точно перестанет работать.

Ну тогда по разным дата-центрам разносить сайты, чего уж там. Интересно, какая CMS работает с функцией exec и еще интересно, почему мы не рассматриваем php как модуль апач? Какие еще отдельные процессы?

На сайте с 20.09.2008
24 марта 2017, 13:25

smart2web:
Ну тогда по разным дата-центрам разносить сайты, чего уж там.
Интересно, какая CMS работает с функцией exec и еще интересно, почему мы не рассматриваем php как модуль апач? Какие еще отдельные процессы?

То есть предполагается выключать функции exec ? Насколько я знаю у Bitrix долгие операции реализованы в том числе через exec (хотя могу ошибаться). Так же бывает нужно вызывать ffmpeg, curl — года 3-4 назад мы собирали статистику по вызовам этих функций и как не странно они используются. Мы как раз и рассматриваем php как модуль apache, но при этом он работает из под разных пользователей. Но тут проблема даже не в PHP. Ок может пользователь будет использовать python, node.js или perl не дай бог. То есть данный вопрос надо решать комплексно, не на уровне отдельно взятого языка с его костылями — а на уровне операционной системы.

>> Какие еще отдельные процессы? Не могу не задать вопрос — а как по вашему работает php как модуль apache ? Обрабатывает все запросы в рамках одного процесса ? =) Или же все таки apache, например создает несколько потомков — передает им обработку запроса, далее в зависимости от сайта потомок суидится в пользователя и уже потом вызывает php в рамках своего процесса для обработки запроса =)

На сайте с 30.12.2015
24 марта 2017, 13:30

alexeyymanikin:
Не могу не задать вопрос — а как по вашему работает php как модуль apache ? Обрабатывает все запросы в рамках одного процесса ? =) Или же все таки apache, например создает несколько потомков — передает им обработку запроса, далее в зависимости от сайта потомок суидится в пользователя и уже потом вызывает php в рамках своего процесса для обработки запроса =)

Согласен, но open_basedir не даст такому процессу попасть выше указанного значения.
На сайте с 20.09.2008
24 марта 2017, 13:38
smart2web:
Согласен, но open_basedir не даст такому процессу попасть выше указанного значения.

Вы мои сообщения читаете ? Это только в том случае если у ваз заблокированы все функции аля exec — что фактически причиняет боль пользователям. И это работает только в случае PHP. А если посмотреть более внимательно http://php.net/manual/ru/ini.core.php open_basedir изменяется PHP_INI_ALL после версии 5.3 что означает http://php.net/manual/ru/configuration.changes.modes.php «Значение может быть установлено отовсюду» — ну кто мешает получив доступ к файлу, изменить .htaccess ? При этом Вы продолжаете уверять меня, что open_basedir защитит сайты пользователей ?

На сайте с 04.01.2012
24 марта 2017, 14:06

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

Алексей, поделитесь пожалуйста ссылочкой, где можно почитать?

NVMe VDS (https://well-web.net/nvme-vps) с поддержкой 24/7 — от 545 руб.! Безлимитный хостинг (https://well-web.net/ssd-hosting) — от 129 руб.! Домен в подарок! Перенос бесплатно! Заказывайте сейчас, и получите скидку 50%! Заходи! (https://well-web.net/limited-offers)

На сайте с 05.06.2007
24 марта 2017, 15:38

Действительно, open_basedir теперь можно менять везде, но практика показывает что вирусня пока не догадывается до отмены open_basedir и заражается обычно только тот сайт который дырявый, возможно ей этого достаточно. Лучше всего не использовать всякие дырявые системы, вовремя обновлять CMS, ну и на крайний случай действительно раскидывать по аккаунтам где уже будет 100%я изоляции. PS> Про систему изоляции бегета хотелось бы тоже почитать, а пока не понятно о чём там речь.

Написал не мало шедевров 😉
На сайте с 26.06.2010
24 марта 2017, 17:48

open_basedir вообще не поможет, нужно изолировать на уровне пользователей. а отключение функций в php это костыли которые только мешают.

На сайте с 09.12.2005
24 марта 2017, 18:40

Dimanych:
Действительно, open_basedir теперь можно менять везде, но практика показывает что вирусня пока не догадывается до отмены open_basedir и заражается обычно только тот сайт который дырявый, возможно ей этого достаточно. Лучше всего не использовать всякие дырявые системы, вовремя обновлять CMS, ну и на крайний случай действительно раскидывать по аккаунтам где уже будет 100%я изоляции.

Зря Вы так думаете, есть и такие, которые не только заражают соседние сайты пользователя, но и например заливают скомпилированную прогу в общедоступную директорию и шлют СПАМ! open_basedir вообще лишний параметр, который только тормозит работу сайтов и ни как не помогает.

MGNHost.ru — полный комплекс хостинг услуг ( https://www.mgnhost.ru ) VPS/VDS на SSD дисках в России / Нидерландах / США от 210 рублей ( https://www.mgnhost.ru/vds.php )

На сайте с 30.12.2015
24 марта 2017, 18:50

globalmoney:
Зря Вы так думаете, есть и такие, которые не только заражают соседние сайты пользователя, но и например заливают скомпилированную прогу в общедоступную директорию и шлют СПАМ!
open_basedir вообще лишний параметр, который только тормозит работу сайтов и ни как не помогает.

Речь не обезопасить сайты в целом от взлома. ТС прекрасно понимает, что это вполне возможно, а разделить, что бы один сайт не заразил другой, а с basedir это в принципе достигается при должных настройках сервера.

Настройка open_basedir на примере VestaCP

В некоторых панелях управления сервером, например VestaCP по-умолчанию директива open_basedir настроена только на запуск php-скриптов внутри директории public_html у домена. Но т.к. ради безопасности нам необходимо разместить файлы проекта выше www, то open_basedir необходимо перенастроить. В противном случае, мы постоянно будем получать ошибку вида File . is not within the allowed path(s).

Можно поменять настройку в основном php.ini распрстранив, таким образом, изменения на весь сервер. Если вы забыли где лежит файл конфигурации то воспользуйтесь командой

$ php -i | grep php.ini

Допустим, нас интересует решение для конкретного домена, а не сервера целиком. На форуме весты есть такое решение: создайте в дополнительный конфигурационный файл /home/%user%/conf/web/httpd.%domain%.conf в котором будет прописано:

  php_admin_value open_basedir none 

Но полностью отключать настройку не всегда безопасно, к тому же, если присмотреться, то в директории /home/%user%/conf/web/ можно найти файл apache2.conf

Открываем его, например, с помощью nano (не забывайте добавлять папаметр -w при открытии конфигурационных файлов)

nano -w home/user/conf/web/apache2.conf

В нём в разделе Directory есть строчка вида

php_admin_value open_basedir /home/user/web/domain/public_html:/home/user/tmp

Здесь указано 2 разрешённых пути, двоеточие — это разделитель между ними. Например, мы хотим разрешить выполнение php в папке project на один уровень выше веб-директории public_html, тогда добавляем в конце строки:

:/home/user/web/domain/project

Сохраняем изменения Ctrl+O, выходим Ctrl+X. Теперь перезапустим апач что бы новые настройки вступили в силу:

etc/init.d/apache2 restart

Всё готово, если что-то не работает ищите опечатку.

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

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