问题
I'm currently migrating my LAMP from my Windows Server to a VPS running Debian 6. Most everything is working, however, one of the PHP scripts was failing to write to its configured log file. I could not determine why, so I wrote a new, simple, contrived PHP script to test the problem.
<?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;
}
?>
However, it fails with the result:
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
- While I would never do it normally, to help diagnose, I set
/var/log/apache2/writetest/writetest.logto chmod 777. - Both the directory and the file are owned by
www-data:www-data. - The file was created with
touch.
I ran strace to verify which process was performing the 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)
I checked and pid 21931 was indeed one of the apache2 child processes running under www-data. As you can see, I also included echo exec('whoami'); in the script which confirmed the script was being run by www-data.
Other notes:
- PHP is not running in safe mode
- PHP
open_basediris not set - Version info:
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 - This is on a VPS running under OpenVZ
- ls -l (file):
-rwxrwxrwx 1 www-data www-data 0 Sep 8 18:13 writetest.log - ls -l (directory):
drwxr-xr-x 2 www-data www-data 4096 Sep 8 18:13 writetest - Apache2's parent process runs under
root, and the child processes underwww-data - selinux is not installed (thanks to Fabio for reminding me to mention this)
- I have restarted apache many times and rebooted the server as well
回答1:
Remember that in order to reach a file, ALL parent directories must be readable by www-data. You strace output seems to indicate that even accessing /var/log/apache2/writetest is failing. Make sure that www-data has permissions on the following directories:
/ (r-x)/var (r-x)/var/log (r-x)/var/log/apache2 (r-x)/var/log/apache2/writetest (rwx)/var/log/apache2/writetest/writetest.log (rw-)
回答2:
Does the php file doing the writing have proper permissions set? Try changing those to see if that's the issue.
回答3:
Could be a SELinux issue, even if Debian doesn't ship it in the default installation your provider could have enabled it. Look for messages in /var/log with
grep -i selinux /var/log/{syslog,messages}
If that's the cause and you need to disable it, here are instructions: look for file /etc/selinux/config, here it's default content. Change SELINUX directive to disabled and reboot the system.
# 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
来源:https://stackoverflow.com/questions/7355780/php-fopen-fails-on-files-even-with-wide-open-permissions