从 PHP 脚本重新启动 PHP-FPM

从 PHP 脚本重新启动 PHP-FPM

我正在运行 LEMP 堆栈,并希望为其编写一个简单的控制面板。

所以,我希望能够php-fpm从 php 脚本重新启动。为了实现这一目标,这就是我所做的。

c像这样创建了一个二进制包装器php-shell.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CMN_LEN 100

int main(int argc, char *argv[])
{
    char cmd[MAX_CMN_LEN] = "", **p;

    if (argc < 2)
    {
        fprintf(stderr, "Usage: ./php_shell terminal_command ...");
        exit(EXIT_FAILURE);
    }
    else
    {
        strcat(cmd, argv[1]);
        for (p = &argv[2]; *p; p++)
        {
            strcat(cmd, " ");
            strcat(cmd, *p);
        }
        system(cmd);
    }

    return 0;
}

这个程序是这样编译的:

gcc php_shell.c -o php_shell

然后我添加了 nginx 用户,如下所示sudo visudo

Defaults:nginx        !requiretty
nginx    ALL=(ALL)    NOPASSWD:/path/to/php_shell

然后我在 php 脚本中执行命令,如下所示:

var_dump(shell_exec('sudo /path/to/php_shell "service nginx restart" 2>&1'));

一旦我运行这个脚本 php 脚本,我就会502 Gateway Error发现所有php-fpm进程都已被终止并且不会启动备份。

有任何想法吗?我这样做错了吗?我希望能够通过执行从 php 脚本重新启动 nginx 服务器service nginx restart。我怎样才能实现这个目标?

答案1

恭喜!您正在向任何可以让您的 nginx 服务器运行任意代码的人授予不受限制的 root 访问权限。您最好确保每个 CGI 脚本和 php 页面以及任何其他可能用于执行任意代码的内容都是安全的。

您的 C 包装器相当于配置 sudo 以允许 nginx 以 root 身份运行任何命令。

就那样做。

为特定命令编写单独的 shell 脚本(或其他)包装器,然后仅向这些包装器脚本授予 sudo 访问权限。例如,/usr/local/sbin/restart-nginx.sh这确实是没有什么但是service nginx restart并给予 nginx sudo 访问该脚本的权限。

然后编写另一个完全独立的脚本来运行,例如,dmidecode -s system-uuid如上一个问题所示。并授予 nginx sudo 访问该脚本的权限。

每个单独的脚本越简单、越简单越好。最安全的是根本不接受任何用户输入,不从命令行或环境变量中进行输入。

如果某些包装器脚本必须接受用户输入,请在使用之前进行完整性检查并清理所有用户提供的输入。并引用你的变量 - 例如总是使用"$variable"而不是不带$variable引号。

如果您的包装器脚本变得过长且复杂,则尝试仅识别需要以 root 身份运行的最小命令或命令集,并将它们编写为单独的脚本(或多个脚本),这些脚本由sudo主脚本调用。即尽可能少地以 root 身份运行。

相关内容