Команда оболочки перезагрузки Nginx не работает в сценарии lua

У меня есть докеризированный сервер Nginx, созданный с базовым образом openresty. Когда вызывается конкретная конечная точка, ей необходимо динамически обновлять конфигурацию nginx. Чтобы изменения отразились, я пытаюсь перезагрузить nginx вскоре после изменений в config.

в контейнере я могу перезагрузить сервер nginx, используя /usr/local/openresty/nginx/sbin/nginx -s reload

когда я пытаюсь использовать то же самое с lua, как показано ниже, он не выдает никаких ошибок, но изменения конфигурации не отражаются.

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

person Sarga    schedule 24.06.2020    source источник


Ответы (2)


Эта команда будет выполняться с привилегиями рабочего процесса 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")
person Ivan Shatsky    schedule 24.06.2020
comment
поправьте меня, если я ошибаюсь, но suid можно использовать только с бинарными исполняемыми файлами, а не с интерпретируемыми сценариями. - person DarkWiiPlayer; 24.06.2020
comment
@DarkWiiPlayer Вы правы, я забыл, что по умолчанию бит suid игнорируется в сценариях оболочки. Мое решение не будет работать, если его не завернуть в какой-нибудь скомпилированный код, например int main() { setuid(0); system( "/usr/local/openresty/nginx/sbin/nginx-reload.sh" ); return 0; } - person Ivan Shatsky; 24.06.2020
comment
Большое спасибо @IvanShatsky и DarkWiiPlayer за то, что нашли время разобраться в деле. Очень ценю это. Попытался бы добавить сценарий оболочки и вызвать выполнение, чтобы запустить его из моего lua - person Sarga; 24.06.2020
comment
@Sarga Вы не должны отмечать ответ как принятый, если только вы не протестируете решение и не убедитесь, что оно работает, чтобы не путать пользователей с похожими вопросами. И, как указал DarkWiiPlayer, скорее всего, это решение не сработает. - person Ivan Shatsky; 24.06.2020
comment
@IvanShatsky system из программы setuid тоже не работает. - person Joseph Sible-Reinstate Monica; 25.06.2020
comment
@IvanShatsky я попробовал решение, и оно сработало для меня. Пришлось немного поработать. Как уже упоминалось, мне пришлось обернуть команду выполнения в скрипт c. Я добавил команду для ее компиляции и установил разрешение пользовательского бита в файле докера, а затем выполнил ее с помощью моего lua. :) - person Sarga; 25.06.2020

Вы можете вообще пропустить вызов nginx и просто отправить сигнал HUP главному процессу, используя LuaJITs FFI.

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 мог писать в него.
  • Включите привилегированный агент< /em> рабочий процесс.
  • Настройте привилегированного рабочего процесса на прослушивание ввода в именованном канале (например, используя модуль ngx.pipe для открытия cat и ожидания ввода) и отправьте сигнал HUP главному процессу.
  • Измените свой код os.execute, чтобы вместо этого написать некоторую строку текста в именованный канал, чтобы привилегированный агент перезагрузил сервер.

РЕДАКТИРОВАТЬ: Если вам не нравится хак cat, вы можете взглянуть на https://github.com/slact/ngx_lua_ipc

Возможно, можно использовать IPC, чтобы все это было автономным в пределах одного экземпляра сервера nginx без какого-либо доступа к файлам.

person DarkWiiPlayer    schedule 24.06.2020