Linux — функция PHP is_writable () всегда возвращает false для каталога с возможностью записи

Я пытаюсь установить на основе PHP пакет программного обеспечения в экземпляре Red Hat 7 Amazon EC2 (ami-8cff51fb), на котором установлены Apache 2.4.6 и PHP 5.4.16 с использованием yum. Установка завершается неудачно, поскольку в ней говорится, что веб-сервер должен иметь доступ к записи для конкретного каталога с разрешениями 0755 или 0775.

Указанный каталог имеет права доступа 0775 с root:apache владение. Я проверил, что процесс httpd выполняется пользователем apache и что пользователь apache является членом группы apache.

Если я редактирую /etc/passwd временно предоставить пользователю apache оболочку входа в систему, а затем su с этой учетной записью, я могу вручную создавать файлы как пользователь apache в каталоге, используя touch команда.

Я взглянул на исходный код сценария установки и обнаружил, что он не работает, потому что PHP is_writable() функция возвращает false для рассматриваемого каталога. Я создал отдельный тестовый скрипт PHP, чтобы изолировать и проверить поведение, которое я вижу:

<?php
$dir = '/var/www/html/limesurvey/tmp';
if (is_writable($dir)) {
echo $dir, ' is writable';
} else {
echo $dir, ' is NOT writable';
}
?>

Это выводит сообщение НЕ для записи. Если я изменю $dir выше, чтобы быть /tmp тогда это правильно выводит, что /tmp доступно для записи.

Если я изменю права доступа к каталогу на 0777 и / или поменяю владельца на apache:apache тогда PHP все еще сообщает, что каталог не доступен для записи. Я даже пытался создать /test каталог, настроенный с теми же правами и владельцем, и мой тестовый сценарий по-прежнему сообщает о невозможности записи.

Я действительно в растерянности, чтобы объяснить это поведение, поэтому любые идеи будут приветствоваться!

Заранее спасибо.


Список каталогов для /var/www/html/limesurvey дается ниже. tmp а также upload каталоги имеют 0775 разрешений в соответствии с Lime Survey Инструкция по установке. test.php мой тестовый скрипт, упомянутый выше.

[ec2-user@ip-xx-x-x-xxx limesurvey]$ pwd
/var/www/html/limesurvey
[ec2-user@ip-xx-x-x-xxx limesurvey]$ ls -al
total 80
drwxr-xr-x. 20 root apache 4096 Mar 30 11:25 .
drwxr-xr-x.  3 root root     23 Mar 25 14:41 ..
drwxr-xr-x.  2 root apache   38 Mar 10 12:56 admin
drwxr-xr-x. 16 root apache 4096 Mar 10 12:56 application
drwxr-xr-x.  3 root apache 4096 Mar 10 12:56 docs
drwxr-xr-x.  2 root apache 4096 Mar 10 12:56 fonts
drwxr-xr-x. 19 root apache 4096 Mar 10 12:56 framework
-rw-r--r--.  1 root apache  429 Mar 10 12:56 .gitattributes
-rw-r--r--.  1 root apache  399 Mar 10 12:56 .gitignore
-rw-r--r--.  1 root apache  296 Mar 10 12:56 .htaccess
drwxr-xr-x.  4 root apache 4096 Mar 10 12:56 images
-rw-r--r--.  1 root apache 6652 Mar 10 12:56 index.php
drwxr-xr-x.  5 root apache   39 Mar 10 12:56 installer
drwxr-xr-x. 89 root apache 4096 Mar 10 12:56 locale
drwxrwxr-x.  2 root apache   39 Mar 25 14:41 logs
drwxr-xr-x.  4 root apache   49 Mar 10 12:56 plugins
-rw-r--r--.  1 root apache   61 Mar 10 12:56 README
drwxr-xr-x.  4 root apache 4096 Mar 10 12:56 scripts
-rw-r--r--.  1 root apache  380 Mar 10 12:56 .scrutinizer.yml
drwxr-xr-x.  5 root apache 4096 Mar 10 12:56 styles
drwxr-xr-x.  5 root apache 4096 Mar 10 12:56 styles-public
drwxr-xr-x. 12 root apache 4096 Mar 10 12:56 templates
-rw-r--r--.  1 root apache  159 Mar 30 11:11 test.php
drwxr-xr-x.  3 root apache   20 Mar 10 12:56 themes
drwxr-xr-x. 26 root apache 4096 Mar 10 12:56 third_party
drwxrwxr-x.  5 root apache   80 Mar 26 13:45 tmp
drwxrwxr-x.  6 root apache   79 Mar 10 12:57 upload

Бег namei -l /var/www/html/limesurvey/tmp дает:

[ec2-user@ip-x-x-x-xxx ~]$ namei -l /var/www/html/limesurvey/tmp
f: /var/www/html/limesurvey/tmp
drwxr-xr-x root root   /
drwxr-xr-x root root   var
drwxr-xr-x root root   www
drwxr-xr-x root root   html
drwxr-xr-x root apache limesurvey
drwxrwxr-x root apache tmp

11

Решение

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

sudo chcon -R -t httpd_sys_rw_content_t tmp
21

Другие решения

в CentOS 6 выше должно быть SELinux включить принудительное исполнение

setenforce Permissive

проверить статус

sestatus

Ссылаться на https://wiki.centos.org/HowTos/SELinux

6

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

namei -l /var/www/html/limesurvey/tmp

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

0

HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1`
sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX tmp
sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX tmp

Взятый непосредственно из руководства по установке Symfony2, это решает проблему с разделением доступа к записи в кэш между инструментами Apache и CLI. Это может работать для вашего tmp каталог, а также.

0

is_writable по умолчанию проверяет только пользователя, а не группу.
Таким образом, даже если ваша группа совпадает и имеет разрешения, is_writable вернет false.
Чтобы ослабить эту проверку, вам нужно установить

safe_mode_gid = On

в конфигурации PHP или измените пользователя соответственно.

0
По вопросам рекламы [email protected]