4

I would like to build a very simple PHP based web based control panel to add and remove users to/from and add and remove sections to/from nginx config files on my linode vps (Ubuntu 8.04 LTS).

What is the most secure way of executing commands as root based on input from a web based control panel?

I am loathe to run PHP as root (even if behind an IP tables firewall) for the obvious reasons.

Suggestions welcome. It must be possible as several commercial (and bloated, for my needs) control panels offer similar functionality.

Thanks

1
  • Have you considered maybe just embedding a Java-based SSH client into an admin portion of you site?
    – jamieb
    Feb 18, 2010 at 7:50

7 Answers 7

2

Create a sudo rule for the user the web server runs as, so it can only run specific commands. To edit a file, for example, you could have the web server make a copy in a directory owned and only writeable by the webserver (so malicious local users can't step on your changes mid-process), and have a sudo rule to copy the edited file into place. You can lock the sudo rules down so that only those commands with specific arguments can be handled.

Also, ensure that you're authenticating users, and ensure that you sanitize any input from the user to stop any shell metacharacters or similar from sneaking in. When adding users, for example, you might verify that the input fits within a maximum length and consists of only letters and number. Using sudo would prevent most things like that anyway, but multiple layers of protection are good. It's not possible to be too paranoid with user input. ;)

Or just install Webmin. :)

2
  • +1 for the sudo rules, -1 for suggesting webmin (which does precisely what OP is trying to avoid, run with fool root privileges). Feb 18, 2010 at 11:21
  • 2
    Webmin runs as root, but authenticates the user and runs commands as either root or a specified user. Coincidentally, sudo is setuid root and authenticates the user, allowing certain users to do certain things as either root or another user. From a security perspective, they're very nearly the same thing with a slightly different interface.
    – dannysauer
    Feb 26, 2010 at 21:44
1

Whatever you do, it will always be a possible security hole.

Some suggestions:

  • Write a simple shell script that executes its input, and have it chown and setuid root; PHP will call it and pass it the supplied command.
  • Use more specific scripts for the various tasks you will perform, and have them setuid root; again, PHP will call them.
  • Write a demon which accepts commands on a TCP socket and executes them, and have it run as root; PHP will connect to it.
  • Anything else based on the concept "have something else on the system that can do what you want as root and have PHP call it".

Nothing of the above seems actually safer (and definitely not simpler) than just having your "control panel" run as root. And most "control panel" packages (such as webmin) just bypass this entirely and run as root.

0

write a cgi script in python, i think it's probably easier. Although it is so much safer, as Massimo said, to get a webmin running...

0

I think you could combine these items to achieve a good level of security:

  • Run PHP as a specific user either via fast-cgi, cgi-bin, or phpsuexec
  • Consider using the Hardened PHP project http://www.hardened-php.net/
  • As suggested, use sudo to get the root level access you require
  • If possible, using SELinux here could give you very good security, but it can be tedious to deploy

Also, though I prefer the approach above, I had a client how simply dumped actions to a file and then had a script process these actions. The script ran via cron every 5 minutes.

Is public access required for this? If not, use IPtables and apache's own Authconfig to protect it from abuse.

4
  • I almost gave you a -1 for suggesting hardened-php. That project is awesome, but its not designed for this. The whole point is that he wants to give PHP LOTS of privileges, not take it away.
    – Rook
    Feb 19, 2010 at 16:11
  • It all depends on how you plan to actually execute the system commands. If you call a system function then having the added protections of the project would be significant. I've seen it in use in several cases precisely for this reason and it works very well. Hardened PHP + Sudo can be a powerful combination. Feb 19, 2010 at 16:25
  • PHP and sudo? Are you mad?
    – pobk
    Feb 20, 2010 at 9:53
  • Its also worth noting that SElinux will block what he's trying to do. Likewise with hardened.
    – zetavolt
    Feb 23, 2010 at 20:50
0

There is cPannel and WebMin that do this, they are also notoriously insecure. The consequences from a hack is also great, you loose your entire system and you will have to reinstall from scratch when you are hacked.

Just like you don't want to use telnet, you don't want to use http. Make sure you use HTTPS, and buy a real certificate, after all throwing your root password over the net is a serious mistake and you want to make sure its going to the right server.

EDIT: You could run cPannel in a chroot, so even if it was compromised you could just make a new chroot. Its also a padded prison that lets you define exactly what root has access to.

4
  • or create your own certificates?
    – Gnudiff
    Feb 19, 2010 at 12:47
  • 1
    No go with a real one. Its only $30 and the whole point is that you want to make sure your typing your ROOT password into your server and not a "Man In the Middle" (MITM).
    – Rook
    Feb 19, 2010 at 16:08
  • Isn't the only difference is that one is validated by a company and one's not?
    – JPerkSter
    Feb 20, 2010 at 10:15
  • 1
    If you buy it then a browser will be able to tell you that you are in fact talking to your server. If you don't buy one, the browser will always throw an error when you visit your server and it will throw the same error when you give your root password to a hacker conducting a MITM attack. There isn't much point in self-singed certs.
    – Rook
    Feb 22, 2010 at 23:28
0

You could symlink the files into a web-root folder, htaccess for semi-security (on top of your php auth), write a script to morph it.. then you just need to restart the nginx process when the files are changed.

www.cyberciti.biz/faq/freebsd-configure-nginx-php-fastcgi-server/

You could use something like the following to monitor the changes, send you an email when they change (with the changes), and restart the nginx process via a script..

http://inotify-tools.sourceforge.net/

Might be overkill when you could detect it via cron every minute or so..

0

Idea number 1: Use puppet to direct the changes to your config files.

If you need to edit the files, then try: Create a PHP script which edits it's own local copy. This then gets checked into a local SVN repository. Then using svn-externals, the only thing you have to do as root is to do an svn update in the nginx config files (which of course you've checked into SVN) and your set.

The update script can run on a cron job.

You must log in to answer this question.