user145447
user145447

Reputation:

How to run PHP exec() as root?

I'm trying to build a firewall manager in PHP, but when I execute, <?php exec('iptables -L'); ?>, the result array is empty.

I have tried, <?php echo exec('whoami'); ?>, and the response is www-data (the user that Apache is using). What can I do to execute the exec function as root? (Preferably without changing the Apache user.)

Upvotes: 37

Views: 106209

Answers (9)

I had a similar issue where I needed to execute Git commands like git reset --hard from a PHP script as the www-data user. Here's how I managed to make it work without changing the PHP user to root:

Solution: Set correct ownership for the web directory:

Ensure that www-data owns the web directory so it has the correct permissions:

chown -R www-data:www-data /var/www

Configure Git to allow safe directory access:

This ensures Git does not throw permission issues when accessed by www-data:

git config --global --add safe.directory /var/www

Grant www-data permission to run Git commands without a password:

To allow the www-data user to run Git commands via sudo, you can add the following line to the sudoers file. It's recommended to create a separate file under /etc/sudoers.d/ for this:

echo "www-data ALL=(ALL) NOPASSWD: /usr/bin/git" | sudo tee /etc/sudoers.d/www-data-git

This ensures that www-data can run git commands as root without requiring a password.

Execute the Git command from PHP using sudo:

In the PHP script, use sudo to execute the git command. Here’s the command I used (example usage):

$strCommand = "echo '' | sudo -S git -C /var/www reset --hard origin/main 2>&1";
exec($strCommand, $output);
echo implode("\n", $output);

echo '' | sudo -S: This sends an empty password to sudo -S because the sudoers configuration allows the git command to run without a password. git -C /var/www reset --hard origin/main: This resets the Git repository to match the remote branch. 2>&1: Redirects both output and error messages for debugging.

Summary: With this setup, I was able to run Git commands through PHP as www-data, using sudo, without needing to change the PHP user to root or provide a password for sudo. This was done inside a Docker container, but it should work in similar environments where you manage sudo permissions for specific commands.

Upvotes: 0

MerlinTheMagic
MerlinTheMagic

Reputation: 605

I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS

After downloading you would simply use the following code:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('iptables -L');
//the return will be a string containing the return of the command
echo $return1;

Upvotes: 2

lumos0815
lumos0815

Reputation: 4326

I know this is an old question

add the user php runs on to the sudo group if it is not already assigned

use sudo -S, so you can pass the password via echo

$exec = "echo your_passwd | /usr/bin/sudo -S your command";
exec($exec,$out,$rcode);

if you have trouble with the paths - use

"bash -lc 'echo your_passwd | /usr/bin/sudo -S your command'"

so you get a new bash that acts like a login shell and has the paths set

check the man pages of sudo

Upvotes: 16

user580858
user580858

Reputation:

You can run sudo through phpseclib, a pure PHP SSH implementation:

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
$ssh->login('username', 'password');

$ssh->read('[prompt]');
$ssh->write("sudo command\n");
$ssh->read('Password:');
$ssh->write("Password\n");
echo $ssh->read('[prompt]');
?>

Upvotes: 13

Gabriel Sosa
Gabriel Sosa

Reputation: 7956

Unless you use suphp and configure it to run as root you wont be able to run any PHP script on behalf of any other system user besides who is running PHP.

Edit:

Just an small idea. Add a queue process in some way and run a cron process in the root's crontab.

Please please be really careful about this. Any injection can literally destroy the system.

Upvotes: 3

James Anderson
James Anderson

Reputation: 27486

Don't do it! You will leave yourself wide open to all sorts of malicious hackery.

Have a look at the "sudo" documentation.

You should be able to set up all the commands you need as "sudo"able scripts. It is much better to write specific scripts with limited functions than to expose the underlying priviledged command.

As in:

exec ('sudo getIpTables.ksh')

Upvotes: 38

Bart van Heukelom
Bart van Heukelom

Reputation: 44134

You can put the required commands in a separate script/executable file (sh, PHP, a real executable, doesn't matter), change its owner to root, and apply "setuid" to it.

This will allow anything and anyone to run this script as root, so you need to make sure that it has it's own security rules for seeing if this is allowed, and is very restricted in what it does.

Upvotes: 4

Collin
Collin

Reputation: 437

This is very unsafe and a bad idea. Rethink your design. If you really want to do this use sudo as advised. An alternative solution might be to go ahead and run as root but do so inside a chroot or a vm image (both of which can be broken out of but still).

Or best of all run as sudo inside a chroot!

Upvotes: 3

Just an assumption - Is this a PHP web app that will do this? This doesn't sound too safe. The app that needs root - could you build that separately and then invoke it from PHP? If not, maybe you can sudo the process so it can run as root.

Upvotes: -2

Related Questions