我正在运行 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.conf
。www-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()