我对任何告诉 nginx 使用新日志文件的命令都有问题。我正在使用 Ubuntu 18.04、nginx/1.14.0、logrotate 3.11.0
如果我手动或通过 logrotate 在 /var/log/nginx 中创建新文件access.log
或error.log
文件,它们不会被使用,而是服务使用旧的日志文件(我已将其重命名为access.log.1
用于此测试,模拟 logrotate 的作用。)
我已经尝试了以下命令(单独)。它们都不会产生任何错误消息,它们都会产生预期的输出。但是 nginx 拒绝停止使用旧日志。
service nginx rotate
invoke-rc.d nginx rotate
kill -USR1 `cat /var/run/nginx.pid`
我还验证了上述.pid
文件在正确的位置。
我能够让日志轮换工作的唯一方法是通过 a service nginx reload
,它可以完成这项工作,但也会重新加载配置文件。我知道重新加载没有停机时间,但我仍然希望尽可能少地重新加载,这就是我想要开始service nginx rotate
工作的原因。
我几乎可以肯定这是由于/var/log
. 最近我们设置了一个 cronjob 来确保日志文件具有安全的权限。这是为了进行审计,因为这家渗透测试公司就日志记录提出了各种安全措施。我们设置的 cronjob 在启动时运行:
#!/bin/bash
setfacl -Rm u::rwx,g::r--,o::--- /var/log
find /var/log -type f -exec chmod g-wx,o-rwx "{}" + -o -type d -exec chmod g-w,o-rwx "{}" +
chmod g+wx /var/log
chown -R www-data:adm /var/log/nginx
下面是运行cronjob后相关目录和文件的权限:
/var/log 目录本身:
drwxrwx--- 14 root syslog 4096 Aug 27 10:01 log
/var/log/nginx 目录本身:
drwxr----- 2 www-data adm 4096 Aug 24 02:25 nginx
以及 /var/log/nginx 的内容(我们在 nginx conf 中使用自定义命名日志):
-rwxr----- 1 www-data adm 0 Aug 24 02:24 access.log
-rwxr----- 1 www-data adm 108 Aug 24 02:24 error.log
-rwxr----- 1 www-data adm 49317 Aug 27 10:11 x3nr0s.access.log
-rwxr----- 1 www-data adm 798 Aug 27 10:02 x3nr0s.error.log
如果我们运行logrotate --force /etc/logrotate.d/nginx -v
(详细),甚至是手动touch
创建新文件,它们会被创建为 640 权限(根据 logrotate 的配置文件)。根据我的阅读,640 就足够了:
-rwxr----- 1 www-data adm 0 Aug 24 02:24 access.log
-rw-r----- 1 www-data adm 0 Aug 27 10:13 error.log
-rwxr----- 1 www-data adm 1972 Aug 27 10:13 error.log.1
-rw-r----- 1 www-data adm 0 Aug 27 10:13 x3nr0s.access.log
-rwxr----- 1 www-data adm 51521 Aug 27 10:13 x3nr0s.access.log.1
-rw-r----- 1 www-data adm 0 Aug 27 10:13 x3nr0s.error.log
-rwxr----- 1 www-data adm 798 Aug 27 10:02 x3nr0s.error.log.1
如您所见,新文件保持为空,并且日志记录继续到旧文件。我还验证了详细的 logrotate 输出,关于 postrotate 部分似乎一切正常。(运行invoke-rc.d nginx rotate
。正如我之前提到的,这个命令似乎没有旋转任何东西......)
作为最后一个测试,我尝试授予用户对新文件的执行权限,并执行了service nginx rotate
. 尽管如此,nginx 仍然使用旧文件。其他一些答案提到检查磁盘空间是否已满。它不是。
非常感谢您的帮助!谢谢。
更多信息
这是我的 /etc/logrotate.d/nginx 配置:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
如上所述,我让 logrotate 和 nginx 正确处理新日志文件的唯一方法是将postrotate
部分替换为service nginx reload
.
这是输出ps -ef | grep nginx
:
root 1367 1 0 10:45 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 1368 1367 0 10:45 ? 00:00:00 nginx: worker process
www-data 1369 1367 0 10:45 ? 00:00:00 nginx: worker process
www-data 1370 1367 0 10:45 ? 00:00:00 nginx: worker process
www-data 1371 1367 0 10:45 ? 00:00:00 nginx: worker process
root 15247 14835 0 11:19 pts/0 00:00:00 grep --color=auto nginx
这是getfacl
/var/log 上的:
# file: var/log
# owner: root
# group: syslog
user::rwx
group::rwx
other::---
这是getfacl
/var/log/nginx 上的:
# file: var/log/nginx
# owner: www-data
# group: adm
user::rwx
group::r--
other::---
这
/etc/logrotate.d/nginx
是默认的,应该可以工作。但是,更改
postrotate.d
命令,强制 nginx 重新加载其配置(并使用新的日志文件)可能是一个快速修复。
通常,当正常工作的服务无法创建/打开/重命名/更改文件时,会涉及访问权限。
此处访问已更改(为了安全起见),但默认 acl 也应该可以工作/安全,不涉及哪个功能强大,但在使用默认选项
setfacl
时不会立即出现。ls
默认 acl 是,对于
/var/log
而默认的 nginx(实际上)是
nginx
很好,/var/log
可能会更紧一点允许
others
访问目录(及以下)但阻止他们列出内容。至于 facl,该
getfacl
命令将列出为 和 实际添加的 ACL ,/var/log
这可能会揭示问题。/var/log/nginx
/var/log/nginx/*
顺便说一句,也做一个
检查安装程序在更新或安装后将设置哪些 ACL,并在必要时更改或添加一行(man dpkg-statoverride)