Nginx reload shell command not working with in lua script

我有一个使用openresty基础镜像创建的docker化的Nginx服务器。当调用特定的端点时,需要动态更新nginx配置文件。为了让更改生效,我尝试在配置更改后立即重新加载nginx。

在容器内部,我可以使用 /usr/local/openresty/nginx/sbin/nginx -s reload 重新加载nginx服务器

但当我尝试使用lua中的相同命令时,它不会报错,但配置更改没有反应。

os.execute("/usr/local/openresty/nginx/sbin/nginx -s reload ")
点赞
用户7121513
用户7121513

这个命令将使用 nginx 工作进程权限运行,您需要以 root 用户执行此命令。您可以尝试为此编写特定的脚本(假设其名称为 /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")
2020-06-24 09:22:44
用户4984564
用户4984564

你可以完全跳过调用nginx并使用LuaJIT的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用户可以写入它
  • 启用_Privileged Agent_工作进程。
  • 设置特权工作程序以在命名管道上监听输入(例如使用ngx.pipe模块打开cat并等待输入),并发送HUP信号到主进程
  • 将您的os.execute代码更改为代替写入一些文本行到命名管道,以使特权代理重新加载服务器。

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

可以使用IPC在单个nginx服务器实例中将整个内容保持为自包含,而无需进行任何文件访问。

2020-06-24 12:51:38