Nginx 重新加载 shell 命令在 lua 脚本中不起作用

Nginx reload shell command not working with in lua script

我有一个用 openresty 基础镜像创建的 dockerised Nginx 服务器。当调用特定端点时,它需要动态更新 nginx 配置。为了反映更改,我正在尝试在配置更改后立即重新加载 nginx。

在容器中,我可以使用 /usr/local/openresty/nginx/sbin/nginx -s reload

重新加载 nginx 服务器

当我尝试在 lua 中使用与下面相同的 with 时,它没有出现任何错误,但配置更改没有得到反映。

os.execute("/usr/local/openresty/nginx/sbin/nginx -s reload ")

此命令将 运行 具有 nginx 工作进程权限,您需要成为根用户才能执行此命令。您可以尝试为此制作一个特定的脚本(假设其名称为 /usr/local/openresty/nginx/sbin/reload-nginx.sh:

#!/bin/sh
/usr/local/openresty/nginx/sbin/nginx -s reload

将此脚本的所有者设置为非 nginx 进程用户(假设其名称为 nginx),并在此脚本上设置 suid

chown nginx /usr/local/openresty/nginx/sbin/reload-nginx.sh
chmod +x /usr/local/openresty/nginx/sbin/reload-nginx.sh
chmod u+s /usr/local/openresty/nginx/sbin/reload-nginx.sh

并尝试从您的 lua 代码执行此脚本:

os.execute("/usr/local/openresty/nginx/sbin/nginx-reload.sh")

您可以完全跳过调用 nginx,只需使用 LuaJITs FFI 向主进程发送一个 HUP 信号。

local process = require 'ngx.process'
local ffi = require 'ffi'
ffi.cdef 'int kill(int pid, int sig);'
ffi.C.kill(process.get_master_pid(), 1)

但是,这并不能解决权限问题。

一个可行的想法是:

  • 使用 mkfifo 设置一个命名管道,让你的 nginx 用户可以写入它
  • 启用 Priviliged Agent 辅助进程。
  • 设置特权工作者监听命名管道上的输入(例如使用ngx.pipe模块打开cat并等待输入)并发送HUP信号到主进程
  • 更改您的 os.execute 代码,改为将一些文本行写入命名管道,以使特权代理重新加载服务器。

编辑:如果您不喜欢 cat hack,您可能想看看 https://github.com/slact/ngx_lua_ipc

可能可以使用 IPC 将整个内容独立保存在单个 nginx 服务器实例中,而无需任何文件访问。