总结

总结

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

semanage permissive -a httpd_t # temporarily make SELinux permissive
semanage fcontext -a -t httpd_sys_content_t  '/opt/x/data/nginx(/.*)?'
restorecon -R -v /opt/x/data/nginx
semanage fcontext -a -t  httpd_log_t '/opt/x/log/nginx(/.*)?'
restorecon -R -v /opt/x/log/nginx

这是我的 nginx.conf:

user Xnginx Xgrp;
worker_processes auto;
error_log /opt/x/log/nginx/error.log;
pid /run/nginx.pid;

以及目录权限:

ls -lZ /opt/X/log/
drwxrwxr-x. Xnginx Xgrp unconfined_u:object_r:httpd_log_t:s0 nginx

我用以下方式启动 Nginx

systemctl start nginx

它给出了

[root@RE1 nginx]# systemctl status nginx
nginx.service - The nginx HTTP and reverse proxy server
  Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
  Active: active (running) since Wed 2020-05-06 09:15:06 CEST; 12min ago
  Process: 109185 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 109182 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 109180 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
  Main PID: 109187 (nginx)
   CGroup: /system.slice/nginx.service
       ├─109187 nginx: master process /usr/sbin/nginx
       ├─109188 nginx: worker process
       ├─109189 nginx: worker process
       ├─109190 nginx: worker process
       └─109191 nginx: worker process

May 06 09:15:06 RE1 systemd[1]: Starting The nginx HTTP and reverse proxy server...
May 06 09:15:06 RE1 nginx[109182]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
May 06 09:15:06 RE1 nginx[109182]: nginx: configuration file /etc/nginx/nginx.conf test is successful
May 06 09:15:06 RE1 systemd[1]: Started The nginx HTTP and reverse proxy server.

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

1     0 109187      1  20   0 131148  2268 sigsus Ss   ?          0:00 nginx: master process /usr/sbin/nginx
5   603 109188 109187  20   0 133632  3544 ep_pol S    ?          0:00  \_ nginx: worker process
5   603 109189 109187  20   0 133632  3544 ep_pol S    ?          0:00  \_ nginx: worker process
5   603 109190 109187  20   0 133632  3544 ep_pol S    ?          0:00  \_ nginx: worker process
5   603 109191 109187  20   0 133632  3544 ep_pol S    ?          0:00  \_ nginx: worker process

最后是问题:

ls -lZ /opt/X/log/nginx/
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access.log
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 error.log

这些文件应该归 Xnginx 所有,而不是 root 所有。为什么?

答案1

总结

这可能是一个错误。当 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.

user www-data;在我们的中使用指令/etc/nginx/nginx.confwww-data有 UID 33。我所有的日志文件都有“.log”后缀。

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

rm /var/log/nginx/*.log

然后,启动 nginx 并记录strace它所做的事情。-k记录调用堆栈。

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

请注意,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
....

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

rm /var/log/nginx/*.log
nginx -s reopen

检查文件是否归以下人员所有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
...

我们现在可以终止 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]

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

相关内容