2 Comments | Jan 24, 2010
Running Commands as Root from PHP
Sometimes you need to automate some terminal commands within your web application. I personally prefer PHP over other server side languages, and in this case its ability to run such commands are fantastinominal. There are a bunch of built in functions for securing/escaping arguments and commands, and a bunch of methods for executing shell commands. The main differences between them are the way output is returned to php. For most cases you should be fine using escapeshellarg() and shell_exec() methods - assuming you're using variables posted to your server code as arguments. You should read up on the various program execution methods over at php.net, and research all the implications and security risks involved in using them.
This post doesn't focus on their use, but instead on how to give Apache(or whatever web server you're using) root access on your server. In fact what you need to do in order to simplify your scripts is allow the Apache process to run root commandswithout a password. That's RIGHT, without a password. This can be exceptionally dangerous so you may want to limit this root access specifically the no-password-necessary root access only to specific programs you need to run from your scripts. Otherwise a small programming error would let malicious people take full control of your web server with ease.
The main purpose of enabling no password root access here is so you can easily run programs with a single command and not worry about being challenged for a password or having to deal with that in your server code. It's potentially more dangerous to store your root password in a public facing script than giving it no-password-root-access to a single program. A fair amount of web software and tools will have versions of theircommands that can be run on a single line for this purpose.
This is for Ubuntu, but should work on most other distros with little tweaking.
First add the following line to your php script:
echo shell_exec("whoami");
This will output the user that Apache, or whatever server is running your php file, is running as on the system. Typically Apache runs as www-data, but your system may be set up differently.
Now open a terminal and ssh into your web server. Run the following command:
sudo visudo
What this does is edit the /etc/sudoers file, however using the visudo command is necessary for changes to properly take effect. Go to the bottom and add the following line to enable the Apache user to sudo without a password:
www-data ALL=NOPASSWD: ALL
The first ALL refers to hosts, the second ALL refers to programs/commands. If you only want to grant Apache sudo access to a specific program replace the second ALLwith the full path to the command file. So even though you will be able to call last from your script without worrying about the path, you need to know the actual path here:
www-data ALL=NOPASSWD: /usr/bin/last
Now you should have a list of shortcuts at the bottom of the terminal, you want to "WriteOut"(ctrl+o) the file which is the same as saving it, you'll be prompted to choose the path to save to, make sure that you're saving it as /etc/sudoers, otherwise it may try save your changes as a copy.
You can now try run last from your php script by adding the following to your php script:
echo shell_exec("sudo last");
Now that it works you may want to remove the echo lines from your script, or test it with a different command since showing the world who's actually running Apache or the output of last is not something you want.