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
-
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.
From Massimo -
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...
From PirosB3 -
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. :)
defraagh : +1 for the sudo rules, -1 for suggesting webmin (which does precisely what OP is trying to avoid, run with fool root privileges).dannysauer : 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.From dannysauer -
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.
Gnudiff : or create your own certificates?Rook : 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).JPerkSter : Isn't the only difference is that one is validated by a company and one's not?Rook : 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.From Rook -
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.
Rook : 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.jeffatrackaid : 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.pobk : PHP and sudo? Are you mad?Zephyr Pellerin : Its also worth noting that SElinux will block what he's trying to do. Likewise with hardened.From jeffatrackaid -
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..
From Grizly -
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.
From pobk -
Thanks all - some great suggestions. The idea of having the whole thing controlled through an SVN server seems like a good one; then I can use some of the ideas herein to check in / check out and restart nginx.
For some reason I've lost access to the first account I posted the question with so don't seem to be able to vote up / accept answers - sorry! Not sure how to remedy.
0 comments:
Post a Comment