Restart PHP-FPM from a PHP script

General Tech Bugs & Fixes 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I am running a LEMP stack and wish to write a simple control panel for it.

So, I want to be able to restart php-fpm from a php script. To achieve this, this is what I did.

Created a binary wrapper in c like this php-shell.c:

#include 
#include 
#include 

#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;
}

This program was compiled like this:

gcc php_shell.c -o php_shell

I have then added nginx user to sudo visudo like this:

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

Then I executed the command in a php script like this:

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

As soon as I run this script php script, I get 502 Gateway Error and it appears all php-fpm processes has been killed off and it does not start back up.

Any ideas? Am I doing this wrong? I want to be able to restart nginx server from php script by executing service nginx restart. How can I achieve this?

profilepic.png
manpreet 2 years ago

Congratulations! You are on the path to giving unrestricted com/tag/root">root access to anyone who can make your nginx server run arbitrary com/tag/code">code. You had better be sure that every single CGI script and php page and anything else that might be used to execute arbitrary com/tag/code">code is secure.

Your C wrapper is equivalent to configuring sudo to allow nginx to run any command at all as com/tag/root">root.

DON'T do it like that.

Write individual shell script (or whatever) wrappers for specific commands and then grant sudo access only to those wrapper scripts. For example, /usr/local/sbin/restart-nginx.sh which does nothing but service nginx restart and give nginx sudo access to that script.

Then write another, completely separate script to run, say, dmidecom/tag/code">code -s system-uuid as in your previous question. And give nginx sudo access to that script too.

The simpler and less complicated each individual script, the better. Safest of all is to take no user input at all, not from the command-line and not from environment variables.

If some of your wrapper scripts must take user input, sanity check and sanitise all user-supplied input before using it. And quote your variables - e.g. always use "$variable" and never just $variablewithout quotes.

If your wrapper scripts are getting excessively long and complicated then try to identify just the minimum command or set of commands that need to be run as root and write them as a separate script (or scripts), which are called by sudo from the main script. i.e. run as little as possible as root.


0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.