Ubuntu Server 22.04 系统
使用 nginx 官方 apt 源安装

默认配置文件中的用户是 user nginx;。
systemd 服务的配置文件中未指定服务的运行用户及组。
nginx 服务启动后,master 进程用户是 root,worker 进程用户是 nginx。
生成的日志文件在 /var/log/nginx/ 路径下,目录的属主和属组是 root root, 自动生成的 access.log等日志文件的属主和属组是 nginx adm。

使用源码包编译安装

nginx 配置文件和 systemd 配置文件中用户的部分和使用 apt 源安装的情况是一样的。
nginx 服务启动后,进程的用户和 apt 源安装后的情况是一样的。
生成的logs日志目录在 nginx 程序目录,权限是 root root,里面自动生成的 access.log等日志文件的属主和属组是 root root,但是权限是 644,nginx 可以正常写入日志。

想知道为什么编译安装的 nginx 生成的日志,属主和属组为什么会是 root?
如何才能让其生成的 log 文件是 nginx 用户?
因为涉及到日志的处理等问题,如果日志文件的属主是 root,处理起来会很麻烦。

还有一点很不理解:网上搜了说,master 进程的用户不受 nginx.conf 配置文件中的 user 用户指定,一般都是 root 。配置文件中的 user 是 worker 进程的用户。而 nginx 日志是 worker 进程写入的。那为什么 log 文件的 owner 是 root root ,权限 644 ,nginx 还能正常的写入日志呢?非 root 用户应该是没有写权限的啊?

可以看下 大兄弟的 #9、# 16 两层楼的内容,感觉情况应该是这样的。nginx 的 bug。
经过测试:

不论 .log 文件的初始情况是什么样的,删除 .log 日志文件之后重启 nginx,自动生成新的 .log 文件属主和属组都是 root root。
执行 kill -USR1 操作后,之前手动 sudo touch 出的 .log 文件(root root),属主会被改成 nginx.conf 中配置的 user 用户(即变为 nginx root)。

你是不是用 root 编译的源码呢?配置日志文件的权限可以在 nginx.conf 中配置,第一行就有一个配置user username;nginx 会用这个用户运行 worker 进程,日志也会是这个用户

apt 安装脚本帮你添加了 nginx 用户和配置文件,编译安装的时候就要你自己搞了

感谢~编译及安装是写了 shell 脚本,脚本的执行使用了 sudo 提权。脚本很简单,就是包含 tar 解压缩,/configure && make && make install 动作。第一条写明了配置文件中已经指定了 user 为 nginx ;第三条已经指明了服务运行后 master 进程用户是 root ,worker 进程用户是 nginx ;配置文件的权限不存在问题,不在这个帖子讨论范围。发帖的目的只是请教 nginx 的 logs 目录及其 access.log 、error.log 文件的所有权问题。

使用源码包编译安装nginx 配置文件。。。。情况是一样的生成的 logs 日志目录在 nginx 程序目录 而不在 /var/log/nginx 下?ngx 启动的时候没用到你的配置吧

感谢,编译安装时,nginx 用户已经手动创建,和 apt 源安装创建的 nginx 用户都是一样的。nginx:x:998:998:nginx user:/nonexistent:/usr/sbin/nologin服务运行没有任何问题,本帖主要是想讨论这两种方法,程序生成的 log 文件的属主和属组为什么不一样的问题。因为这牵扯到非 nginx 程序本身的,nginx 日志处理问题。比如说用第三方程序分割、归档、检索 nginx 日志。

那你对比一下 systemd 服务文件nginx.service中的内容,是不是 apt 安装的有指定usergroup

好吧怪我,把源码安装的情况简写了。编译安装后1. nginx.conf 中指定的 user 为 nginx ,与用 apt 源安装时的配置文件中一致。2. systemd 服务配置中,未指定 User 和 Group ,与用 apt 源安装的情况下的 systemd 配置文件情况一致。nginx 启动及工作都正常,没问题,本帖讨论的仅仅是 《生成的 log 日志文件为什么属主和属组不一样》的问题。因为这牵扯到第三方程序处理 nginx 日志。

apt 安装的 nginx ,初始日志文件是安装完后的善后脚本( /var/lib/dpkg/info/nginx-common.postinst )里创建的,每天日志切分后的维护是在 /etc/logrotate.d/nginx 里配置的。这两个操作都把新的日志文件设置成 owner 为 www-data:adm ,设置 mode 为 0640

#7 superuser.com/questions/1549120/nginx-creates-log-files-owned-by-root-instead-of-specified-user找到个贴,疑似是 Ngx 某些版本的 bug

我这里说的 www-data ,对应你的 nginx 用户

感谢~以下是使用 apt 源安装时自动配置为 systemd 服务的配置文件ini[Unit]Description=nginx - high performance web serverDocumentation= nginx.org/en/docs/After=network-online.target remote-fs.target nss-lookup.targetWants=network-online.target[Service]Type=forkingPIDFile=/var/run/nginx.pidExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.confExecReload=/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=NginxAfter=network-online.target remote-fs.target nss-lookup.targetWants=network-online.target[Service]Type=forkingPIDFile=/usr/local/nginx/logs/nginx.pidExecStartPre=/usr/local/nginx/sbin/nginx -tExecStart=/usr/local/nginx/sbin/nginx# 用于防止出现 pid 文件读取错误,这是个官方 bugExecStartPost=/bin/sleep 0.1ExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s TERM $MAINPID# 是否使用私有的 tmp 目录PrivateTmp=true# 重启策略Restart=on-failureRestartSec=5s[Install]WantedBy=multi-user.target难道是 PrivateTmp=true 这个设置缓存目录为私有这个配置有问题吗?

感谢大佬,贴子里说的情况好像很有理。那问题来了,我现在用的最新的稳定版 1.26.0 ,那这个问题是无解了吗...那可要了命了

“apt 安装的善后脚本” 是不是只能在安装完成后才能被调用一次?那为什么我两种方法安装的 nginx ,都删除日志文件后,sudo systemctl stop/start nginx ,重启 nginx 让它重新创建日志文件,创建出的文件还是和原来的情况一样呢?即 apt 安装的 nginx ,自动创建的日志是 nginx:adm ;编译安装的 nginx ,自动创建的日志是 root:root 。

#12 要不换吧 ;(我下了个 nginx/1.26.0 ,编译安装,user www-data跑起来也出你这问题,logs/* 都是 root

换是什么意思 /手动笑哭在写业务系统的部署脚本,离线部署,有几个公司自己开发的 nginx 模块,换是不可能换的了...要从 centos 换到 Ubuntu ,而且要求规范部署方式,加强安全。以前 centos 都是 root 用户一把梭,所有程序都是 root 起,所有文件都是 root root ,没这档子事...

#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 生成的文件

#15 追加个贴 trac.nginx.org/nginx/ticket/1686

我是看了有一些类似的相关反馈和讨论,但是没有找到有解决办法。而且我很纳闷,为什么这个问题没很多讨论和关注呢?难道大家都是 root 用户一把梭的吗?

#18 也许是合理的吧。 当前正在写入的日志文件 644 root:root ,从权限角度代表非特权用户能读不能改

是啊,非特权用户不能改,那 worker 进程的用户是 nginx ,为什么能呼呼得写入日志呢?

#20 em... 你再看下 #16 或者 #17

哦哦谢谢老哥,刚没看到你#16 的回复。如果你这楼说的是对的,那就明白了。我删了 apt 源安装的 nginx 的 log 文件,重启 nginx ,重新生成的 log 文件 owner 确实成了 root root 。那貌似是个无解的问题...