分享一个遇到的 Nginx 命令引发的故障

 2天前     14  

文章目录

提到 nginx -t 命令,绝大多数人的第一反应是 “测试 Nginx 配置文件语法是否正确”—— 毕竟执行后看到 “syntax is ok” 和 “test is successful”,就默认它只是个 “语法检查工具”。

分享一个遇到的 Nginx 命令引发的故障

但最近一次线上故障,让我彻底刷新了对这条命令的认知:它居然会悄悄修改服务器目录权限,甚至直接导致业务卡顿崩溃!

一、突发故障:页面频繁卡顿,日志报满 “权限拒绝”

某天突然收到业务反馈:某页面多次加载卡顿、频繁报 “502 Bad Gateway”,用户无法正常操作。

分享一个遇到的 Nginx 命令引发的故障

第一时间查看 Nginx 错误日志,发现大量类似报错,核心信息全是 “权限拒绝”:

[crit] 421611#421611: *429 open() "/var/lib/nginx/tmp/proxy/664/02/0000000027" failed (13: Permission denied) while reading upstream, client:
16:48:57 [crit] 421611#421611: *399 open() "/var/lib/nginx/tmp/proxy/666/02/0000000026" failed (13: Permission denied) while reading upstream, client: , server: _, request: "GET /hp-prod/js/dist/block-editor.min.js?ver=b3b0b55b35e04df52f7c HTTP/1.1", upstream: "http://:9080/hp-prod/js/dist/block-editor.min.js?ver=b3b0b55b35e04df52f7c", host: "8.153.203.10", referrer: "http://hppd-admin/post.php"

日志指向很明确:Nginx 要读取 / 写入代理临时文件(/var/lib/nginx/tmp/proxy/)时,没有权限—— 这些临时文件是 Nginx 转发上游服务(如 WordPress 、后端 API )时,用来缓存大响应的关键文件,没权限操作就会导致请求中断。

二、紧急修复:麻溜恢复业务

既然是权限问题,先定位 Nginx 的运行用户:

ps aux | grep nginx

输出显示,Nginx worker 进程的运行用户是 app-u(这是我们之前为了安全,专门创建的低权限账号)。

再检查临时目录权限:

ls -ld /var/lib/nginx/tmp/proxy/

结果出乎意料:proxy 目录及所有子文件的属主 / 属组,居然变成了 nobody( Linux 默认的匿名用户)——app-u 对这些文件没有读写权限,自然会报错。

紧急执行权限修复命令:

# 递归将临时目录的属主/属组改为 app-u 
chown -R app-u:app-u /var/lib/nginx/tmp/ 
# 确保目录有读写执行权限 
chmod -R 755 /var/lib/nginx/tmp/

修复后通知用户重试,页面加载恢复正常,故障暂时解决。

三、溯源:是谁 “偷偷” 改了权限?

业务恢复后,核心问题来了:/var/lib/nginx/tmp/ 原本是 app-u 权限,为什么会变成 nobody

我们翻了故障前 1 小时的服务器操作日志(通过操作记录日志文件),发现一个关键操作:**故障前 2 分钟,有同事用 root 账号执行了 nginx -t -c /path/to/nginx.conf**。

“不就是测试个配置吗?怎么会改权限?” 带着疑问,去看了当时执行的 nginx.conf,发现配置文件里有一行:

user nobody; # 指定 Nginx 运行用户为 nobody

但这里有个矛盾:我们实际启动 Nginx 时,用的是 app-u 账号,且启动命令里没指定配置文件(默认加载 /etc/nginx/nginx.conf,其中 user app-u;)—— 那同事手动指定的这个配置文件,为什么会影响目录权限?

四、测试验证:nginx -t 居然真的会改权限!

为了验证猜想,我在测试环境复现了整个过程:

  1. 初始状态:用 app-u 启动 Nginx ,/var/lib/nginx/tmp/ 属主是 app-u,权限正常;
  2. 执行命令:切换到 root 账号,执行 nginx -t -c /path/to/test.conf(这个 test.conf 里配置了 user nobody;);
  3. 检查结果:执行后立即查看 tmp 目录权限 ——proxyclient_body 等子目录的属主,果然从 app-u 变成了 nobody

至此真相大白: nginx -t 不仅会检查配置语法,还会根据配置文件中的 user 指令,自动创建 / 修复 Nginx 所需的临时目录(如 tmp/proxytmp/client_body),并将这些目录的属主改为 user 指令指定的用户

之前同事用 root 执行 nginx -t -c 错误配置文件 时,配置里的 user nobody; 触发了 Nginx 的 “目录权限修复” 逻辑 —— 直接把原本 app-u 权限的临时目录,改成了 nobody 权限,最终导致业务故障。

五、后续整改

这次故障完全是 “认知盲区” 导致的,后续我们做了 3 项整改,彻底杜绝同类问题:

1. 规范配置文件:user 指令与运行用户强一致

所有 Nginx 配置文件的 user 指令,必须与实际启动 Nginx 的账号保持一致 —— 比如用 app-u 启动,就统一写 user app-u;,禁止出现 nobodyroot 等不匹配的用户。

同时将核心配置文件(如 /etc/nginx/nginx.conf)设为只读,避免误修改:

chmod 444 /etc/nginx/nginx.conf

2. 平时变更类相关操作禁止使用 root 账号

3. 日志监控告警:提前发现权限问题

通过写脚本监控错误日志中的错误关键字,错误次数,一旦触发阈值就告警

最后:

以前总觉得 nginx -t 是 “安全无害” 的命令,这次故障才意识到:任何看似简单的命令,都可能藏着你不知道的细节

尤其是 Nginx 这类高频使用的工具,建议多翻官方文档(比如 nginx -t 的官方说明里其实提到了 “会验证配置相关的目录权限”),避免因 “想当然” 踩坑

分享一个遇到的 Nginx 命令引发的故障 分享一个遇到的 Nginx 命令引发的故障
本文源自: Yangsh853,由麻辣香锅于2天前整理编辑,共 2546 字。
链接地址:分享一个遇到的 Nginx 命令引发的故障 | 麻辣香锅,转载请注明出处!

您可能感兴趣的

暂无评论

暂无评论...