我正在将我的LAMP从我的Windows服务器迁移到运行Debian 6的VPS。大多数工作都正常,但是,其中一个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确实是在www-data
下运行的apache2子进程之一。如您所见,我还在脚本中包含echo exec('whoami');
,该脚本确认脚本由www-data
运行。
其他说明:
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
2.6.32-238.19.1.el5.028stab092.2 #1 SMP Thu Jul 21 19:23:22 MSD 2011 x86_64 GNU/Linux
-rwxrwxrwx 1 www-data www-data 0 Sep 8 18:13 writetest.log
drwxr-xr-x 2 www-data www-data 4096 Sep 8 18:13 writetest
root
下运行,子进程在www-data
答案 0 :(得分:13)
请记住,为了访问文件,所有父目录必须可由www-data读取。 strace输出似乎表明即使访问 /var/log/apache2/writetest
也失败了。确保www-data具有以下目录的权限:
/ (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-)
答案 1 :(得分:0)
写文件的php文件是否设置了适当的权限?尝试更改这些以查看是否存在问题。
答案 2 :(得分:0)
可能是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