RHEL + PHP: запись файлов вне /var/www/html?

Я пытаюсь открыть файл для чтения/записи. Я разрабатывал на Ubuntu, и у меня не было никаких проблем. Теперь пришло время развертывания на сервере RHEL, и я обнаружил, что, похоже, есть какое-то ограничение на расположение записываемого файла.

В RHEL я не могу открыть файл, если он не находится в /var/www/html. Я не могу понять, как разрешить другие местоположения. Мне нужно манипулировать файлами на другом томе по причинам управления дисковым пространством.

Ниже приведен фрагмент кода, который отлично работает в Ubuntu, несмотря ни на что, но ломается в RHEL, если файл находится за пределами корневого веб-сайта:

$repometa = fopen( "/path/to/file/it/does/exist/and/has/good/perms", "r+b");

Фактическая ошибка выглядит следующим образом, что странно, потому что разрешения в порядке (принадлежит пользователю «apache», с 0644 разрешениями на файл, 755 на каталоги).

fopen(<thefile>): failed to open stream: Permission denied

Может ли кто-нибудь указать мне на документы, в которых описывается, как восстановить конфигурацию Apache/PHP RHEL, чтобы разрешить запись в альтернативные места в файловой системе?

Спасибо, ~ Пол


person PaulProgrammer    schedule 25.01.2012    source источник
comment
Выбрал ядерный вариант: удалить selinux   -  person PaulProgrammer    schedule 25.01.2012


Ответы (3)


Как написано на странице руководства httpd_selinux(8), вы должны дать файлам и каталогам определенные файловые контексты, если хотите иметь возможность читать или писать в них. Подробности смотрите на справочной странице, имея в виду, что PHP-скрипты запускаются как демон, если только вы специально не настроили PHP для работы в качестве CGI.

person Ignacio Vazquez-Abrams    schedule 25.01.2012
comment
Возможно, вы правы, но я не могу разобраться в справочных страницах, чтобы понять, что разрешает доступ для чтения/записи пользователю apache. Любые указатели на хороший учебник? - person PaulProgrammer; 25.01.2012
comment
Ничто не может предоставить доступ пользователю apache. Вы должны предоставить доступ демону, работающему в домене. Это делается с помощью контекстов файлов, перечисленных на странице руководства. - person Ignacio Vazquez-Abrams; 25.01.2012
comment
Отлично. Я до сих пор не понимаю, что означают контексты на странице руководства. Есть ли какой-либо контекст о контекстах? - person PaulProgrammer; 25.01.2012
comment
Я внес изменения в возможный ответ (выше этого), если это поможет... :) - person summea; 25.01.2012
comment
@user1168588: user1168588: Это просто тег объекта файловой системы, который SELinux рассматривает как часть своего механизма больших правил для определения того, разрешен ли запрошенный доступ. - person Ignacio Vazquez-Abrams; 25.01.2012
comment
Я понимаю механику, но специфика того, как настроен движок правил и на что он смотрит при каких условиях, загадочна. - person PaulProgrammer; 25.01.2012
comment
Таинственный не станет его трогать. Добро пожаловать в SELinux. Вам следует следить за /var/log/audit/audit.log и проверять инструмент audit2allow. Параметр --why может предоставить большое количество разумно поддающейся исследованию информации, но это всегда будет зависеть от конкретного случая. Я не видел исчерпывающего руководства «все в одном», чтобы не сделать SELinux головной болью для PHP-разработчиков, которым необходимо работать с файловой системой. - person Charles; 25.01.2012
comment
Причина, по которой нет исчерпывающего руководства, заключается в том, что SELinux постоянно меняется по мере улучшения. Кроме того, общее руководство по всему, что разработчику PHP на самом деле нужно знать о том, как заставить SELinux работать, уместилось бы в тройной брошюре. - person Ignacio Vazquez-Abrams; 25.01.2012
comment
Так что же произойдет, если SELinux отключен? Как этот ответ решает вопрос ОП, если проблема все еще существует с отключенным SELinux? - person Mike Kormendy; 29.01.2017

Чтобы добавить некоторые особенности к принятому ответу, у меня также была именно эта проблема, и эта команда исправила ее для меня.

chcon -R -t httpd_sys_content_t /path/to/file/it/does/exist/and/has/good/perms
person casaram    schedule 14.01.2013
comment
СПАСИБО. Иногда руководства сбивают с толку без работающего соответствующего примера. - person ehfeng; 29.03.2013

Похоже на проблему с правами пользователя и/или группы. Файл сам может быть доступен для записи... (как вы упомянули в своем прекрасном имени пути), но, возможно, пользователю apache (или как бы он ни назывался) это не разрешено внести какие-либо изменения в файл за пределами каталога /var/www/html по умолчанию?

Любой способ внести изменения в файл внутри /var/www/html, а затем взять другой сценарий оболочки (и/или пользователя) и переместить его в нужный каталог?

Интересно, что это будет работать на Ubuntu, а не на RHEL; может быть, RHEL более строг в отношении пользователей и групп?

В стороне: в общем, может быть безопаснее, чтобы PHP не писал в файлы за пределами каталогов www... :)

ИЗМЕНИТЬ

По подсказке @Ignacio(1), возможно, сработает что-то вроде этого: http://us2.php.net/manual/en/function.fopen.php#56551

Если это то, что вам нужно все время, вы можете попробовать ввести это в командной строке:

/usr/sbin/setsebool -P httpd_can_network_connect=1

Я все еще был бы осторожен с манипулированием файлами PHP за пределами папки www... но, надеюсь, это поможет...!

(1) http://linux.die.net/man/8/httpd_selinux

person summea    schedule 25.01.2012
comment
Я почти уверен, что права пользователя на каталог и файл верны - пользователь и группа apache владеют как файлом, так и путем, и имеют 644/755 соответственно. - person PaulProgrammer; 25.01.2012
comment
Это одна из причин, почему я не люблю RHEL — он настроен так, чтобы быть безопасным для людей, которые не думают о безопасности, но ограниченным для людей, которым нужна небольшая гибкость. - person PaulProgrammer; 25.01.2012
comment
Я знаю, что Вы имеете ввиду; это похоже на то, что произошло для этого пользователя: .com/questions/3882244/php-fopen-permission-denied - person summea; 25.01.2012