Nginx 创建由 root 而不是指定用户拥有的日志文件

Leo*_*rak 2 nginx centos-7

我正在运行 CentOS 7.7,我想在自定义用户下运行 Nginx,并具有自定义 www 和日志位置。我已经使用了 SELinux,所以我启用了我的自定义目录:

\n\n
semanage permissive -a httpd_t # temporarily make SELinux permissive\nsemanage fcontext -a -t httpd_sys_content_t  '/opt/x/data/nginx(/.*)?'\nrestorecon -R -v /opt/x/data/nginx\nsemanage fcontext -a -t  httpd_log_t '/opt/x/log/nginx(/.*)?'\nrestorecon -R -v /opt/x/log/nginx\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的 nginx.conf:

\n\n
user Xnginx Xgrp;\nworker_processes auto;\nerror_log /opt/x/log/nginx/error.log;\npid /run/nginx.pid;\n
Run Code Online (Sandbox Code Playgroud)\n\n

以及目录权限:

\n\n
ls -lZ /opt/X/log/\ndrwxrwxr-x. Xnginx Xgrp unconfined_u:object_r:httpd_log_t:s0 nginx\n
Run Code Online (Sandbox Code Playgroud)\n\n

我启动 Nginx

\n\n
systemctl start nginx\n
Run Code Online (Sandbox Code Playgroud)\n\n

它给出了

\n\n
[root@RE1 nginx]# systemctl status nginx\nnginx.service - The nginx HTTP and reverse proxy server\n  Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)\n  Active: active (running) since Wed 2020-05-06 09:15:06 CEST; 12min ago\n  Process: 109185 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)\n  Process: 109182 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)\n  Process: 109180 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)\n  Main PID: 109187 (nginx)\n   CGroup: /system.slice/nginx.service\n       \xe2\x94\x9c\xe2\x94\x80109187 nginx: master process /usr/sbin/nginx\n       \xe2\x94\x9c\xe2\x94\x80109188 nginx: worker process\n       \xe2\x94\x9c\xe2\x94\x80109189 nginx: worker process\n       \xe2\x94\x9c\xe2\x94\x80109190 nginx: worker process\n       \xe2\x94\x94\xe2\x94\x80109191 nginx: worker process\n\nMay 06 09:15:06 RE1 systemd[1]: Starting The nginx HTTP and reverse proxy server...\nMay 06 09:15:06 RE1 nginx[109182]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nMay 06 09:15:06 RE1 nginx[109182]: nginx: configuration file /etc/nginx/nginx.conf test is successful\nMay 06 09:15:06 RE1 systemd[1]: Started The nginx HTTP and reverse proxy server.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以看到子进程在用户下运行,而主进程以 root 身份运行

\n\n
1     0 109187      1  20   0 131148  2268 sigsus Ss   ?          0:00 nginx: master process /usr/sbin/nginx\n5   603 109188 109187  20   0 133632  3544 ep_pol S    ?          0:00  \\_ nginx: worker process\n5   603 109189 109187  20   0 133632  3544 ep_pol S    ?          0:00  \\_ nginx: worker process\n5   603 109190 109187  20   0 133632  3544 ep_pol S    ?          0:00  \\_ nginx: worker process\n5   603 109191 109187  20   0 133632  3544 ep_pol S    ?          0:00  \\_ nginx: worker process\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后是问题:

\n\n
ls -lZ /opt/X/log/nginx/\n-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access.log\n-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 error.log\n
Run Code Online (Sandbox Code Playgroud)\n\n

这些文件应该属于 Xnginx,而不是 root。为什么?

\n

mat*_*att 9

太长了;博士

这可能是一个错误。当 nginx 启动时,它会创建日志文件,其中ngx_init_cycle()似乎没有调用chown()日志文件。但是,当您指示 nginx 重新打开文件 ( nginx -s reopen) 时,它会通过 来执行此操作ngx_reopen_files(),这会调用chown().

此外,nginx从不使用指定的组user <user> [group]指令中指定的组。

调查

一、版本:

root@69ef55b3f57d:/# nginx -v
nginx version: openresty/1.13.6.
Run Code Online (Sandbox Code Playgroud)

user www-data;在我们的/etc/nginx/nginx.conf.www-dataUID 33。我的所有日​​志文件都有“.log”后缀。

首先,让我们删除日志文件,以便 nginx 必须创建它们:

rm /var/log/nginx/*.log
Run Code Online (Sandbox Code Playgroud)

然后,启动 nginx 并记录strace它做了什么。-k记录调用堆栈。

root@69ef55b3f57d:/# strace -o /out.log -k -e trace=%file /usr/local/openresty/bin/openresty -g 'daemon off;'
Run Code Online (Sandbox Code Playgroud)

请注意,nginx 将继续在这里运行,直到我们杀死它,因此请切换到另一个终端窗口。

确认日志已创建且所有者为root:root

ls -l /var/log/nginx/*.log
....
-rw-r--r-- 1 root root 0 Oct  6 09:02 /var/log/nginx/access.log
....
Run Code Online (Sandbox Code Playgroud)

删除旧文件,以便 nginx 必须重新创建它们,并要求 nginx 重新打开日志文件:

rm /var/log/nginx/*.log
nginx -s reopen
Run Code Online (Sandbox Code Playgroud)

检查这些文件是否属于www-data:root

ls -l /var/log/*.log
...
rw-r--r-- 1 www-data root 0 Oct  6 09:03 /var/log/nginx/access.log
...
Run Code Online (Sandbox Code Playgroud)

我们现在可以杀死 nginx,在原来的终端中点击CTRL+C(或使用kill

现在,让我们看看 strace 记录了什么:

root@69ef55b3f57d:/# grep -A5 -n /var/log/nginx/access /out.log
1162:openat(AT_FDCWD, "/var/log/nginx/access.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 5
1163- > /lib/x86_64-linux-gnu/libpthread-2.27.so(open64+0x4b) [0x11d2b]
1164- > /usr/local/openresty/nginx/sbin/nginx(ngx_init_cycle+0x982) [0xc7132]
1165- > /usr/local/openresty/nginx/sbin/nginx(main+0x891) [0xb4061]
1166- > /lib/x86_64-linux-gnu/libc-2.27.so(__libc_start_main+0xe7) [0x21b97]
1167- > /usr/local/openresty/nginx/sbin/nginx(_start+0x2a) [0xb443a]
--
1226:openat(AT_FDCWD, "/var/log/nginx/access.log", O_WRONLY|O_CREAT|O_APPEND, 0644) = 4
1227- > /lib/x86_64-linux-gnu/libpthread-2.27.so(open64+0x4b) [0x11d2b]
1228- > /usr/local/openresty/nginx/sbin/nginx(ngx_reopen_files+0x91) [0xc7db1]
1229- > /usr/local/openresty/nginx/sbin/nginx(ngx_master_process_cycle+0x410) [0xdca80]
1230- > /usr/local/openresty/nginx/sbin/nginx(main+0xa75) [0xb4245]
1231- > /lib/x86_64-linux-gnu/libc-2.27.so(__libc_start_main+0xe7) [0x21b97]
--
1233:stat("/var/log/nginx/access.log", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
1234- > /lib/x86_64-linux-gnu/libc-2.27.so(__xstat64+0x15) [0x10f775]
1235- > /usr/local/openresty/nginx/sbin/nginx(ngx_reopen_files+0xb7) [0xc7dd7]
1236- > /usr/local/openresty/nginx/sbin/nginx(ngx_master_process_cycle+0x410) [0xdca80]
1237- > /usr/local/openresty/nginx/sbin/nginx(main+0xa75) [0xb4245]
1238- > /lib/x86_64-linux-gnu/libc-2.27.so(__libc_start_main+0xe7) [0x21b97]
--
1240:chown("/var/log/nginx/access.log", 33, -1) = 0
1241- > /lib/x86_64-linux-gnu/libc-2.27.so(chown+0x7) [0x1113e7]
1242- > /usr/local/openresty/nginx/sbin/nginx(ngx_reopen_files+0xd8) [0xc7df8]
1243- > /usr/local/openresty/nginx/sbin/nginx(ngx_master_process_cycle+0x410) [0xdca80]
1244- > /usr/local/openresty/nginx/sbin/nginx(main+0xa75) [0xb4245]
1245- > /lib/x86_64-linux-gnu/libc-2.27.so(__libc_start_main+0xe7) [0x21b97]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的chown(),仅在重新打开日志文件时调用ngx_reopen_files()