2

I am running CentOS 7.7 and I want to run Nginx under custom user with custom www and log locations. I have already hit SELinux so I enabled my custom directories:

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

This is my nginx.conf:

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

And the directory rights:

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

I start Nginx with

systemctl start nginx

And it gives

[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.

I can see the subprocesses running under the user while the master process run as 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

And finally the problem:

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

The files were supposed to be owned by Xnginx, not root. Why?

1 Answer 1

9

tl;dr

This might be a bug. When nginx starts it creates log files in ngx_init_cycle() which does not seem to call chown() on the log files. However, when you instruct nginx to reopen the files (nginx -s reopen), it'll do that through ngx_reopen_files(), which does call chown().

Furtheremore, nginx never uses group specified in user <user> [group] directive.

Investigation

First, version:

root@69ef55b3f57d:/# nginx -v
nginx version: openresty/1.13.6.

I use user www-data; directive in our /etc/nginx/nginx.conf. www-data has UID 33. All of my log files have '.log' suffix.

First, let's remove the log files so that nginx has to create them:

rm /var/log/nginx/*.log

Then, start nginx and record with strace what it does. -k records call stack.

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

Note that nginx will keep running here until we kill it, so switch to another terminal window.

Confirm that logs have been created and are owned by root:root:

ls -l /var/log/nginx/*.log
....
-rw-r--r-- 1 root root 0 Oct  6 09:02 /var/log/nginx/access.log
....

Remove the old files so that nginx will have to create them again, and ask nginx to reopen log files:

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

Check that the files are owned by 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
...

We can now kill nginx, in the original terminal just hit CTRL+C (or use kill)

Now, let's see what strace recorded:

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]

As you can see chown() is called only when reopening log files, in ngx_reopen_files()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .