root操作Nginx导致用户组错误

问题

某年某月某日临近中午,用户突然反应系统出了问题,微信小程序的几个界面加载异常,不能正常访问。紧急排查发现,后端应用有大量的如下错误日志,错误信息SSL peer shut down incorrectly字面上看上去是HTTPS请求Nginx后SSL握手错误,于是再去查看Nginx的日志。

1
2
3
4
5
6
Error while extracting response for type [class java.lang.String] and content type [application/json;charset=utf-8]; nested exception is javax.net.ssl.SSLException: SSL peer shut down incorrectly
org.springframework.web.client.RestClientException: Error while extracting response for type [class java.lang.String] and content type [application/json;charset=utf-8]; nested exception is javax.net.ssl.SSLException: SSL peer shut down incorrectly
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:725)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:435)

查看Nginx日志后发现果然Nginx也有大量的报错,如下,字面意思就是Nginx自动生成的临时文件夹client_body_tempproxy_temp的读写权限错误。

1
2
3
4
5
6
7
2020/12/08 11:39:19 [crit] 3844#3844: *1686658178 open() "/opt/nginx/client_body_temp/0007652979" failed (13: Permission denied)
2020/12/08 11:39:19 [crit] 3844#3844: *1686658280 open() "/opt/nginx/client_body_temp/0007652980" failed (13: Permission denied)
2020/12/08 11:39:19 [crit] 3844#3844: *1686658233 open() "/opt/nginx/proxy_temp/1/98/0007652981" failed (13: Permission denied) while reading upstream
2020/12/08 11:39:21 [crit] 3842#3842: *1686658542 open() "/opt/nginx/client_body_temp/0007652982" failed (13: Permission denied)
2020/12/08 11:39:21 [crit] 3844#3844: *1686658318 open() "/opt/nginx/client_body_temp/0007652983" failed (13: Permission denied)
2020/12/08 11:39:23 [crit] 3844#3844: *1686651044 open() "/opt/nginx/client_body_temp/0007652984" failed (13: Permission denied)
2020/12/08 11:39:23 [crit] 3844#3844: *1686658745 open() "/opt/nginx/client_body_temp/0007652985" failed (13: Permission denied)

于是再转头查看文件夹的权限情况,输出如下,果然这两个文件夹本应该所属nginx用户,但现在却显示所属nobody用户。紧急修改文件夹权限组后,Nginx不再输出错误日志,后端服务也恢复正常。

1
2
3
4
5
6
7
8
9
drwx------  2 nobody nobody   6 Dec 10 11:26 client_body_temp
drwxr-xr-x 5 nginx nginx 4.0K Nov 13 01:48 conf
drwx------ 2 nobody nobody 6 Jul 12 2017 fastcgi_temp
drwxr-xr-x 2 nginx nginx 56 Apr 7 2020 html
drwxr-xr-x 3 nginx nginx 20K Dec 10 03:26 logs
drwx------ 12 nobody nobody 96 Dec 25 2017 proxy_temp
drwxr-xr-x 2 nginx nginx 19 Jul 12 2017 sbin
drwx------ 2 nobody nobody 6 Jul 12 2017 scgi_temp
drwx------ 2 nobody nobody 6 Jul 12 2017 uwsgi_temp

原因

如果Nginx非root用户启动后,再以root用户执行nginx -t命令,会修改client_body_tempproxy_temp等临时文件夹的权限,文件夹的用户组变为nobody,导致原Nginx进程用户没有权限读写受到影响的临时文件夹。

而这次导致事故的罪魁祸首是同事使用阿里云提供的安全扫描工具对系统进行扫描,但扫描工具本身的问题,以root用户对Nginx执行了操作导致了临时文件夹用户组被自动修改成了nobody

复现

1
2
3
4
5
6
7
8
9
10
11
[root@localhost nginx]# ll
total 4
drwx------. 2 webapp webapp 6 Jan 31 05:50 client_body_temp
drwxr-xr-x. 2 webapp webapp 4096 Jan 31 05:52 conf
drwx------. 2 webapp webapp 6 Jan 31 05:50 fastcgi_temp
drwxr-xr-x. 2 webapp webapp 40 Jan 31 05:50 html
drwxr-xr-x. 2 webapp webapp 58 Jan 31 05:50 logs
drwx------. 2 webapp webapp 6 Jan 31 05:50 proxy_temp
drwxr-xr-x. 2 webapp webapp 19 Jan 31 05:50 sbin
drwx------. 2 webapp webapp 6 Jan 31 05:50 scgi_temp
drwx------. 2 webapp webapp 6 Jan 31 05:50 uwsgi_temp
1
2
3
[root@localhost nginx]# ./sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful
1
2
3
4
5
6
7
8
9
10
11
[root@localhost nginx]# ll
total 4
drwx------. 2 nobody webapp 6 Jan 31 05:50 client_body_temp
drwxr-xr-x. 2 webapp webapp 4096 Jan 31 05:52 conf
drwx------. 2 nobody webapp 6 Jan 31 05:50 fastcgi_temp
drwxr-xr-x. 2 webapp webapp 40 Jan 31 05:50 html
drwxr-xr-x. 2 webapp webapp 58 Jan 31 05:50 logs
drwx------. 2 nobody webapp 6 Jan 31 05:50 proxy_temp
drwxr-xr-x. 2 webapp webapp 19 Jan 31 05:50 sbin
drwx------. 2 nobody webapp 6 Jan 31 05:50 scgi_temp
drwx------. 2 nobody webapp 6 Jan 31 05:50 uwsgi_temp

如上,以root用户对Nginx执行nginx -t命令后,几个临时文件夹的用户组被修改成了nobody

总结

慎用root用户,不要以root用户对Nginx进行任何操作!