PHP fopen () терпит неудачу в файлах даже с широко открытыми разрешениями

В настоящее время я переношу свою LAMP с моего Windows Server на VPS, на котором запущен Debian 6. Большинство из них работает, однако один из скриптов PHP не смог записать в его настроенный файл журнала. Я не мог определить, почему, поэтому я написал новый, простой, надуманный PHP-скрипт для проверки проблемы.

<?php ini_set('display_errors', 1); error_reporting(E_ALL); echo exec('whoami'); $log = fopen('/var/log/apache2/writetest/writetest.log', 'a'); if ($log != NULL) { fflush($log); fclose($log); $log = NULL; } ?> 

Однако он терпит неудачу с результатом:

 www-data Warning: fopen(/var/log/apache2/writetest/writetest.log): failed to open stream: Permission denied in /var/www/_admin/phpwritetest.php on line 5 
  • Хотя я бы никогда не делал этого нормально, чтобы помочь диагностировать, я установил /var/log/apache2/writetest/writetest.log в chmod 777.
  • И каталог, и файл принадлежат www-data:www-data .
  • Файл был создан с touch .

Я strace чтобы проверить, какой процесс выполняет open:

 [pid 21931] lstat("/var/log/apache2/writetest/writetest.log", 0x7fff81677d30) = -1 EACCES (Permission denied) [pid 21931] lstat("/var/log/apache2/writetest", 0x7fff81677b90) = -1 EACCES (Permission denied) [pid 21931] open("/var/log/apache2/writetest/writetest.log", O_RDWR|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied) 

Я проверил, и pid 21931 действительно был одним из дочерних процессов apache2, работающих под www-data . Как вы можете видеть, я также включил echo exec('whoami'); в скрипте, который подтвердил, что скрипт запускается www-data .

Другие примечания:

  • PHP не работает в безопасном режиме
  • PHP open_basedir не установлен
  • Информация о версии: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze3 with Suhosin-Patch mod_ssl/2.2.16 OpenSSL/0.9.8o
  • uname -a: 2.6.32-238.19.1.el5.028stab092.2 #1 SMP Thu Jul 21 19:23:22 MSD 2011 x86_64 GNU/Linux
  • Это работает на VPS под управлением OpenVZ
  • ls -l (файл): -rwxrwxrwx 1 www-data www-data 0 Sep 8 18:13 writetest.log
  • ls -l (каталог): drwxr-xr-x 2 www-data www-data 4096 Sep 8 18:13 writetest
  • Родительский процесс Apache2 работает под root , а дочерний процесс обрабатывается по www-data
  • selinux не установлен (спасибо Фабио, чтобы напомнить мне об этом)
  • Я многократно перезапускал apache и перезагружал сервер.

Solutions Collecting From Web of "PHP fopen () терпит неудачу в файлах даже с широко открытыми разрешениями"

Помните, что для доступа к файлу ВСЕ родительские каталоги должны быть доступны для чтения через www-data. Вы вывод strace, похоже, указывают на то, что даже доступ к /var/log/apache2/writetest выполняется. Убедитесь, что www-data имеет разрешения для следующих каталогов:

  • / (rx)
  • /var (rx)
  • /var/log (rx)
  • /var/log/apache2 (rx)
  • /var/log/apache2/writetest (rwx)
  • /var/log/apache2/writetest/writetest.log (rw-)

Имеет ли файл php, выполняющий запись, соответствующие разрешения? Попытайтесь изменить их, чтобы увидеть, если это проблема.

Может быть проблемой SELinux, даже если Debian не отправит ее в установку по умолчанию, которую поставщик мог бы включить. Поиск сообщений в /var/log с помощью

 grep -i selinux /var/log/{syslog,messages} 

Если это причина, и вам нужно ее отключить, вот инструкции: найдите файл /etc/selinux/config , здесь это содержимое по умолчанию. Измените директиву SELINUX на disabled и перезагрузите систему.

 # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - SELinux is fully disabled. SELINUX=disabled # SELINUXTYPE= type of policy in use. Possible values are: # targeted - Only targeted network daemons are protected. # strict - Full SELinux protection. SELINUXTYPE=targeted