Ubuntu Server 22.04 系统
user nginx;
。master
进程用户是 root
,worker
进程用户是 nginx
。/var/log/nginx/
路径下,目录的属主和属组是 root root
, 自动生成的 access.log
等日志文件的属主和属组是 nginx adm
。logs
日志目录在 nginx 程序目录,权限是 root root
,里面自动生成的 access.log
等日志文件的属主和属组是 root root
,但是权限是 644
,nginx 可以正常写入日志。想知道为什么编译安装的 nginx 生成的日志,属主和属组为什么会是 root
?
如何才能让其生成的 log 文件是 nginx
用户?
因为涉及到日志的处理等问题,如果日志文件的属主是 root
,处理起来会很麻烦。
可以看下 @retanoj 大兄弟的 #9、# 16 两层楼的内容,感觉情况应该是这样的。nginx 的 bug。 经过测试:
APPEND 最后定稿版绝对不再修改(第一版)
用 logrotate 日志分割工具试了下,貌似只要 logrotate 分割使用 root 权限,对日志分割和重新生成都无影响。
所以这个问题其实是没什么大的影响。所以官方才十几年也没修?
1
dier 236 天前
你是不是用 root 编译的源码呢?配置日志文件的权限可以在 nginx.conf 中配置,第一行就有一个配置`user username;`
nginx 会用这个用户运行 worker 进程,日志也会是这个用户 |
2
qingbaihe 236 天前
apt 安装脚本帮你添加了 nginx 用户和配置文件,编译安装的时候就要你自己搞了
|
3
GoodRui OP @dier 感谢~
编译及安装是写了 shell 脚本,脚本的执行使用了 sudo 提权。脚本很简单,就是包含 tar 解压缩,/configure && make && make install 动作。 第一条写明了配置文件中已经指定了 user 为 nginx ; 第三条已经指明了服务运行后 master 进程用户是 root ,worker 进程用户是 nginx ; 配置文件的权限不存在问题,不在这个帖子讨论范围。发帖的目的只是请教 nginx 的 logs 目录及其 access.log 、error.log 文件的所有权问题。 |
4
retanoj 236 天前
使用源码包编译安装
nginx 配置文件。。。。情况是一样的 生成的 logs 日志目录在 nginx 程序目录 而不在 /var/log/nginx 下? ngx 启动的时候没用到你的配置吧 |
5
GoodRui OP @qingbaihe 感谢,编译安装时,nginx 用户已经手动创建,和 apt 源安装创建的 nginx 用户都是一样的。
nginx:x:998:998:nginx user:/nonexistent:/usr/sbin/nologin 服务运行没有任何问题,本帖主要是想讨论这两种方法,程序生成的 log 文件的属主和属组为什么不一样的问题。 因为这牵扯到非 nginx 程序本身的,nginx 日志处理问题。比如说用第三方程序分割、归档、检索 nginx 日志。 |
6
dier 236 天前
那你对比一下 systemd 服务文件`nginx.service`中的内容,是不是 apt 安装的有指定`user`和`group`
|
7
GoodRui OP @retanoj 好吧怪我,把源码安装的情况简写了。
编译安装后 1. nginx.conf 中指定的 user 为 nginx ,与用 apt 源安装时的配置文件中一致。 2. systemd 服务配置中,未指定 User 和 Group ,与用 apt 源安装的情况下的 systemd 配置文件情况一致。 nginx 启动及工作都正常,没问题,本帖讨论的仅仅是 《生成的 log 日志文件为什么属主和属组不一样》的问题。因为这牵扯到第三方程序处理 nginx 日志。 |
8
adoal 236 天前
apt 安装的 nginx ,初始日志文件是安装完后的善后脚本( /var/lib/dpkg/info/nginx-common.postinst )里创建的,每天日志切分后的维护是在 /etc/logrotate.d/nginx 里配置的。这两个操作都把新的日志文件设置成 owner 为 www-data:adm ,设置 mode 为 0640
|
9
retanoj 236 天前
|
10
adoal 236 天前
我这里说的 www-data ,对应你的 nginx 用户
|
11
GoodRui OP @dier 感谢~
以下是使用 apt 源安装时自动配置为 systemd 服务的配置文件 ```ini [Unit] Description=nginx - high performance web server Documentation=https://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)" ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" [Install] WantedBy=multi-user.target ``` 以下是编译安装时使用的手写 systemd 服务的配置文件 ```ini [Unit] Description=Nginx After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx # 用于防止出现 pid 文件读取错误,这是个官方 bug ExecStartPost=/bin/sleep 0.1 ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID # 是否使用私有的 tmp 目录 PrivateTmp=true # 重启策略 Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target ``` 难道是 PrivateTmp=true 这个设置缓存目录为私有这个配置有问题吗? |
13
GoodRui OP @adoal “apt 安装的善后脚本” 是不是只能在安装完成后才能被调用一次?那为什么我两种方法安装的 nginx ,都删除日志文件后,sudo systemctl stop/start nginx ,重启 nginx 让它重新创建日志文件,创建出的文件还是和原来的情况一样呢?即 apt 安装的 nginx ,自动创建的日志是 nginx:adm ;编译安装的 nginx ,自动创建的日志是 root:root 。
|
15
GoodRui OP @retanoj 换是什么意思 /手动笑哭
在写业务系统的部署脚本,离线部署,有几个公司自己开发的 nginx 模块,换是不可能换的了...要从 centos 换到 Ubuntu ,而且要求规范部署方式,加强安全。以前 centos 都是 root 用户一把梭,所有程序都是 root 起,所有文件都是 root root ,没这档子事... |
16
retanoj 236 天前
@GoodRui #15
好吧,你这问题真涨知识(其实我之前也不知道情况是这样) 给个结论:Nginx 会以 master 进程的属主创建 access.log & error.log ,并且将其文件描述符通过 fork 方式给到子进程( worker ),所以 worker 可以写入而无关权限。 当发生 log rotate 时,Nginx 会将旧日志权限转变为 nginx.conf 中 user 字段配置的用户。 至于 apt 装的为啥日志是 nginx:adm ,是因为装好之后 access.log 和 error.log 已经生成好了。你删掉他们再启动 nginx ,会看到还是 root 生成的文件 |
17
retanoj 236 天前
|
18
GoodRui OP @retanoj 我是看了有一些类似的相关反馈和讨论,但是没有找到有解决办法。
而且我很纳闷,为什么这个问题没很多讨论和关注呢?难道大家都是 root 用户一把梭的吗? |
22
GoodRui OP @retanoj 哦哦谢谢老哥,刚没看到你#16 的回复。如果你这楼说的是对的,那就明白了。我删了 apt 源安装的 nginx 的 log 文件,重启 nginx ,重新生成的 log 文件 owner 确实成了 root root 。那貌似是个无解的问题...
|
23
adoal 236 天前
@GoodRui 人肉测试了一下,删掉日志后 systemd 重新启动 nginx.service 新的日志文件是 root 的了……
不过 logrotate -f 手工强制卷了一下日志,归档完了后,新的日志文件就又是 www-data:adm 了。 ` root@asusz97a:/var/log/nginx# ls -al 总计 12 drwxr-xr-x 2 root adm 4096 4 月 29 日 20:23 . drwxr-xr-x 25 root root 4096 4 月 28 日 00:00 .. -rw-r--r-- 1 root root 162 4 月 29 日 20:26 access.log -rw-r--r-- 1 root root 0 4 月 29 日 20:23 error.log root@asusz97a:/var/log/nginx# cat access.log ::1 - - [29/Apr/2024:20:26:35 +0800] "GET / HTTP/1.1" 200 615 "-" "curl/8.7.1" ::1 - - [29/Apr/2024:20:26:38 +0800] "GET /1434 HTTP/1.1" 404 153 "-" "curl/8.7.1" root@asusz97a:/var/log/nginx# logrotate -f /etc/logrotate.d/nginx root@asusz97a:/var/log/nginx# ls -al 总计 12 drwxr-xr-x 2 root adm 4096 4 月 29 日 20:26 . drwxr-xr-x 25 root root 4096 4 月 28 日 00:00 .. -rw-r----- 1 www-data adm 0 4 月 29 日 20:26 access.log -rw-r--r-- 1 root root 162 4 月 29 日 20:26 access.log.1 -rw-r--r-- 1 www-data root 0 4 月 29 日 20:23 error.log ` |
24
adoal 236 天前
如果系统负载不是很高的话,还有一个办法,让 nginx 把日志写进 syslog ,在 rsyslog 的配置里去指定落盘位置和文件权限,甚至可以转发到中央日志服务器,本机就不管这些糟心事了。
|
25
ShuWei 236 天前
master 进程在创建 worker 进程的时候,如果需要,会同步创建日志文件并调整日志文件的权限配置,在这些操作之后,才将 worker 进程降权,所以这个时候创建的日志文件的所有者会是高权限的帐户,大部份时候就是 root
|
27
GoodRui OP @adoal 感谢~
貌似虽然权限有 bug ,但是用 logrotate 分割日志貌似也没什么影响...所以也不用纠结了...需要注意的好像就是 logrotate 的执行权限需要使用 root. |
28
adoal 235 天前
@GoodRui logrotate 可以设置切分的周期,最小单位是每小时切一次。如果日志增长不均匀,怕每小时切一次在低增长时段切得太碎,还可以设置仅超过指定的大小才切分。
|
30
adoal 235 天前
@GoodRui 哦,我误解你的意思了,以为“量大的用户一天一个 error.log 就几个 G 了...”这句话是嫌按天切分单个文件太大,主贴和后面说“用第三方程序分割、归档、检索 nginx 日志”是想找更细粒度的切法
|
31
adoal 235 天前
另外 logrotate 基本上不用自己考虑用什么用户身份手工调用的问题,因为它是放在/etc/cron.xxxxly/ 下面的配置里自动定时调用的
|
32
GoodRui OP @adoal 首先,如果只是配置 logrotate 分割配置文件让它自动分割的话,所有的分割任务会被打散在凌晨 3:15~3:45 之间的随机时间点执行。我上面有提到这个对于我们的业务来说是不适用的。我们要求必须 0:00~23:59 为一个天日志。所以我们现在目前都是使用定时任务调用 logrotate 执行,精确控制日志的起始时间节点。
其次,logrotate 的分割任务配置文件中可以指定该任务运的运行用户,会影响分割出的日志文件 owner 和权限。如果这里指定的用户有问题,会导致分割失败,分割后应用程序无权限写入日志文件等问题。 |