nginx以root启动时,如果配置文件中没有指定user指令,那么默认会设定user为nobody, 数字为65534。而如果使用非root用户启动,那么nginx则不处理用户,直接以当前用户启动worker进程。
nginx的启动过程中的函数ngx_init_cycle会调用函数ngx_create_paths创建临时文件目录。在创建目录后,也会对目录的属主进行处理。如果属主不同于user指令配置的用户,那么就会调用chown更改属主为user配置的用户。
在执行nginx -t时,nginx也会调用函数ngx_init_cycle, 也就是在执行nginx -t时也有可能更改临时目录的属主,从而导致在运行的nginx worker进程没有权限读取临时目录导致业务异常。
比如,以nginx用户启动nginx, 此时临时目录属主为nginx。
1 2
| nginx 273095 0.0 0.0 26788 384 ? Ss 10:11 0:00 nginx: master process ./sbin/nginx nginx 273096 0.0 0.0 27156 1948 ? S 10:11 0:00 nginx: worker process
|
1 2 3 4 5 6 7 8 9 10 11
| [nginx@dev02 nginx]$ ls -l total 4 drwx------. 2 nginx nginx 6 Dec 18 10:10 client_body_temp drwxr-xr-x. 2 nginx root 4096 Dec 18 10:11 conf drwx------. 2 nginx nginx 6 Dec 18 10:10 fastcgi_temp drwxr-xr-x. 2 nginx root 40 Oct 24 17:22 html drwxr-xr-x. 2 nginx root 58 Dec 18 10:11 logs drwx------. 2 nginx nginx 6 Dec 18 10:10 proxy_temp drwxr-xr-x. 2 nginx root 48 Dec 18 10:07 sbin drwx------. 2 nginx nginx 6 Dec 18 10:10 scgi_temp drwx------. 2 nginx nginx 6 Dec 18 10:10 uwsgi_temp
|
当再次以root帐号运行nginx -t时,临时目录属主被修改为nobody。此时,worker进程不再有权限读取临时目录,从而会导致业务异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| [root@dev02 nginx] total 4 drwx------. 2 nginx nginx 24 Dec 18 10:31 client_body_temp drwxr-xr-x. 2 nginx root 4096 Dec 18 10:33 conf drwx------. 2 nginx nginx 6 Dec 18 10:10 fastcgi_temp drwxr-xr-x. 2 nginx root 40 Oct 24 17:22 html drwxr-xr-x. 2 nginx root 58 Dec 18 10:32 logs drwx------. 2 nginx nginx 6 Dec 18 10:10 proxy_temp drwxr-xr-x. 2 nginx root 48 Dec 18 10:07 sbin drwx------. 2 nginx nginx 6 Dec 18 10:10 scgi_temp drwx------. 2 nginx nginx 6 Dec 18 10:10 uwsgi_temp [root@dev02 nginx] nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@dev02 nginx] total 4 drwx------. 2 nobody nginx 24 Dec 18 10:31 client_body_temp drwxr-xr-x. 2 nginx root 4096 Dec 18 10:33 conf drwx------. 2 nobody nginx 6 Dec 18 10:10 fastcgi_temp drwxr-xr-x. 2 nginx root 40 Oct 24 17:22 html drwxr-xr-x. 2 nginx root 58 Dec 18 10:32 logs drwx------. 2 nobody nginx 6 Dec 18 10:10 proxy_temp drwxr-xr-x. 2 nginx root 48 Dec 18 10:07 sbin drwx------. 2 nobody nginx 6 Dec 18 10:10 scgi_temp drwx------. 2 nobody nginx 6 Dec 18 10:10 uwsgi_temp
|
从上面的示例可以看到临时目录属主都被修改为nobody。
这时请求访问到临时目录,会报错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| [root@dev02 nginx]# curl --data-binary @1m.bin http://127.0.0.1:8080/upload -v * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0) > POST /upload HTTP/1.1 > Host: 127.0.0.1:8080 > User-Agent: curl/7.61.1 > Accept: */* > Content-Length: 1048576 > Content-Type: application/x-www-form-urlencoded > Expect: 100-continue > < HTTP/1.1 100 Continue < HTTP/1.1 500 Internal Server Error < Server: nginx/1.29.4 < Date: Thu, 18 Dec 2025 02:42:40 GMT < Content-Type: text/html < Content-Length: 177 < Connection: close < <html> <head><title>500 Internal Server Error</title></head> <body> <center><h1>500 Internal Server Error</h1></center> <hr><center>nginx/1.29.4</center> </body> </html> * we are done reading and this is set to close, stop send * Closing connection 0
|
查看nginx的error.log可以看到worker进程没有权限读取临时目录:
1
| 2025/12/18 10:42:40 [crit] 273290#0: *13 open() "/usr/local/nginx/client_body_temp/0000000002" failed (13: Permission denied), client: 127.0.0.1, server: localhost, request: "POST /upload HTTP/1.1", host: "127.0.0.1:8080"
|
已给官方提交Pull Request, 在nginx -t时不修改临时目录权限,但官方认为修改属主是配置检测的必要步骤,拒绝该Pull Request。
因而这种场景下,需要我们自行切换到nginx worker进程的用户,再执行nginx -t。