我在 CentOS 上设置了一个简单的 LAMP 堆栈。Apache 使用 vhosts 设置,每个开发人员在其用户文件夹中都有自己的 Web 文件。目录结构如下(对于用户test
):
/home/test
|_ apache
|_ domain1.com
|_ backups
|_ conf
|_ vhost.conf
|_ logs
|_ errors.log
|_ images.log
|_ web.log
|_ private
|_ public
vhost 配置位于 vhost.conf 文件中。首次设置配置时,logs 中的日志文件不存在,因此当我运行以下命令时,apache 会抛出错误service httpd restart
:
(13)Permission denied: httpd: could not open error log file /home/test/apache/domain1.com/logs/error.log.
Unable to open logs
我尝试httpd -X
以 root 身份运行,它创建了日志文件(具有 root 所有权/组)。我以为这是一个确保文件存在、组设置为apache
可写的情况(所以我不必让整个目录属于apache
组并可写),但这让我很困惑:
[root@dev logs]# ls -al
total 16
drwxr-xr-x. 2 test developers 4096 Apr 18 21:02 .
drwxr-xr-x. 8 test developers 4096 Apr 18 20:25 ..
-rw-r--r--. 1 test developers 1818 Apr 18 21:02 error.log
-rw-r--r--. 1 test developers 14 Apr 18 20:25 .gitignore
-rw-r--r--. 1 test developers 0 Apr 18 20:54 image.log
[root@dev logs]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [FAILED]
[root@dev logs]# touch web.log
[root@dev logs]# chown test:developers web.log
[root@dev logs]# service httpd restart
Stopping httpd: [FAILED]
Starting httpd: [ OK ]
我很困惑,因为 apache 以用户身份运行apache
,不应该对日志具有写权限,对吗?事实上,我甚至可以这样做:
[root@dev logs]# rm -f ./*.log
[root@dev logs]# touch {error.log,image.log,web.log}
[root@dev logs]# ls -al
total 12
drwxr-xr-x. 2 test developers 4096 Apr 18 21:10 .
drwxr-xr-x. 8 test developers 4096 Apr 18 20:25 ..
-rw-r--r--. 1 root root 0 Apr 18 21:10 error.log
-rw-r--r--. 1 test developers 14 Apr 18 20:25 .gitignore
-rw-r--r--. 1 root root 0 Apr 18 21:10 image.log
-rw-r--r--. 1 root root 0 Apr 18 21:10 web.log
[root@dev logs]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
我现在拥有 root 拥有的日志文件,它仍然可以启动 - 并且它也会写入它们 - 如果我跟踪 web.log 并浏览该页面,日志就会开始显示。
我显然没有完全理解这里的一些内容,那么我遗漏了什么?我宁愿不必手动创建日志文件并允许 apache 自行执行此操作,但无论如何,我只是想了解为什么会发生这种情况 - 尤其是当我允许 PHP 处理文件时。
更新
audit.log
根据要求,当我尝试启动 apache 时,如果日志文件不存在,则看到以下内容:
type=AVC msg=audit(1397906748.752:49390): avc: denied { write } for pid=19433 comm="httpd" name="logs" dev=md2 ino=7210204 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir
type=SYSCALL msg=audit(1397906748.752:49390): arch=c000003e syscall=2 success=no exit=-13 a0=7f9bb740e598 a1=80441 a2=1b6 a3=752e6f632e74756f items=0 ppid=19432 pid=19433 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=128 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
在日志存在的情况下运行时,不会向日志中添加任何其他内容。Permission denied: httpd: could not ...
错误来自一般日志。
答案1
您使用 touch 创建单个文件,然后通过 chown 更改文件所有者。Apache 自己创建日志文件时,需要对包含目录chown -R
是需要的。在指定的日志目录上使用(大写 R = 递归)。
答案2
我刚才也遇到了同样的问题。@Tim Alexander 给我指明了正确的方向。暂时禁用 selinux 证明问题出在 selinux 配置上。
因此,在进一步谷歌搜索之后,我发现了一个建议,基本上是说确保在虚拟主机目录上复制 /var/www/html 上的任何 selinux 配置。
我做的第一件事就是重申我时不时遇到的配置文件中的 selinux 问题,我在这里写了一篇博客:http://blog.ciuly.com/my-server/apache-on-linux-could-not-open-configuration-file-permission-denied/
但这不是问题所在。然而,我进入 /var/www 并发出“ls -Z”,结果显示
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
所以我现在要做的就是
chcon -R system_u:object_r:httpd_sys_content_t:s0 /www/
刷新浏览器现在可以正确显示站点索引,但error_log中仍然有“无法打开日志文件”的错误。
然后我又仔细读了一遍https://wiki.centos.org/HowTos/SELinux
此时,一个好主意是
sealert -a /var/log/audit/audit.log
尽管 wiki 确实说要 grep audit.log 并将其仅传递给 sealert,但我发现我想解决所有 selinux 问题,而不仅仅是现在困扰我的问题 :)
回到我们手头的问题,sealert 显示以下相关警报:
SELinux is preventing /usr/sbin/rotatelogs from search access on the directory /etc/httpd
sealater 建议执行以下操作
#grep rotatelogs /var/log/audit/audit.log | audit2allow -M mypol
#semodule -i mypol.pp
这确实解决了日志问题。
所以,每年当我在 centos 5.x/6.x 上使用 apache 建立新网站时,我都会遇到 3 个 selinux 问题,而且我仍然需要用 google 查找。每次都是这样。
答案3
您已将文件的所有权更改为可由组读取/执行,但不可由组写入,我认为这就是您的问题所在。您可能可以通过 chmod 664 使文件可由所有者和组读取和写入(并可由任何人读取)。它们不需要是可执行的。
答案4
我有同样的问题,vhost 日志在创建时始终由具有 640 权限的 root 拥有,一个解决方法是编写一个脚本来 chmod 或 chown vhost 日志文件名的权限,在文件名末尾使用通配符来捕获日期格式,然后在文件末尾 cron 该脚本并将其设置为每小时一次或每天一次,然后您的 vhost loggs 将具有您想要的权限