Search code examples
phpbashapiroot

How to create an API of some shell commands, and allow access to them via PHP?


I want to do some tasks on my server that require root shell access. I want to make a simple API that I can access from PHP.

The things I want to achieve is:

  • clone from one database to another. The databases are owned by different users:

    mysqldump -h localhost -u SOURCE_USER -pSOURCEPASSWD SOURCE_DB | mysql -h localhost -u DEST_USER -pDEST_PASS DEST_DB

  • copy files from one user public_html to another:

    cp -R SOURCE_DIR DEST_DIR

I have working bash-scripts for both those tasks.

I do not want to give PHP full root access to the server, since that would be crazy, but instead:

How can I make specified bash-scripts executable from a PHP-file in one linux-user's public_html directory?

Alternatively: How can I give root shell access (via shell_exec) to ONE specified PHP-file on a server.


Solution

  • You could use this project: Github. It allows PHP to obtain and interact with a real Bash shell even as root without running the web server as root.

    After composer/downloading you would simply use the following code:

    //read the documentation: here you get a root shell if you allowed sudo
    $shellObj    = \MTS\Factories::getDevices()->getLocalHost()->getShell("bash", true);
    
    //OR if you did not want to give the webserver sudo access, then you can use this syntax:
    $shellObj       = \MTS\Factories::getDevices()->getLocalHost()->getShell("bash", false);
    \MTS\Factories::getActions()->getRemoteUsers()->changeUser($shellObj, 'root', 'rootPassword');
    
    //In both cases you now have a shell as root. This really is a bash shell, its not just wrapping the PHP shell functions.
    
    //All you have left is to issue commands just like you would on a bash prompt
    $strCmd = "mysqldump -h localhost -u SOURCE_USER -pSOURCEPASSWD SOURCE_DB | mysql -h localhost -u DEST_USER -pDEST_PASS DEST_DB";
    
    //for the vast majority of commands that finish within 10 sec you need only issue the command
    $return  = $shellObj->exeCmd($strCmd);
    echo $return;// return from your command
    
    //However if your command runs for more than 10 sec, you must set a timeout. e.g.
    //timeout in miliseconds
    $timeout = 20000;
    $return  = $shellObj->exeCmd($strCmd, null, $timeout);
    echo $return;// return from your command
    

    Feel free to issue more commands on the $shellObj, its a bash shell ready to take orders and as i said ready the documentation.