Running commands though PHP/Perl scripts as a priviledged user on Linux
Background: I am writing a script for a company that will allow users to create FTP accounts through a web interface. In the background, the script must run a bunch of commands:
- Add the user to the system (useradd)
- Open and edit various files
- mail the user via sendmail
and a few other things...
I'm basically looking for the most secure way of doing th开发者_如何学Pythonis. I've heard of the setuid method, the sudo method, and of course, running httpd as a priviledged user. There will be sanity checks on the data entered of course before any commands are executed (ie. only alphanumeric characters in usernames)
What is the method used by the popular scripts out there (webmin for example), as it must be fairly secure?
I would set up a queue that the web-bound script can write to.
Then I'd have some privileged process read from that queue and take appropriate action. You could drive a command-line script via a cron job, or write a little daemon in PHP that checks the queue and does the work more frequently than cron allows.
That way, the only code that can run privileged is your little worker script, and you don't need to provide any path for the web-bound script to gain the necessary but dangerous privileges.
Create a script that accepts a command line option, validates it, and execs useradd. Add your httpd's user to the sudoers file with a NOLOGIN directive, JUST for that one process.
That way, you don't have to worry about writing a daemon that will always run with root privileges, and your script would also return immediately. If you just used a setuid root script, other users on the same system could exec your script (unless you checked their real user ID) .
I'll start by saying that running httpd as root is a very bad idea.
The safest way to do this is have complete privilege separation between the webserver UI and the effector - one obvious way of doing that is to run a server as root accepting local connections only which the UI sends its requests to (a simple way of doing this is via inetd/xinetd - which means you don't have to bother with all the complications of establishing a daemon process).
You would also need some sort of trust mechanism between the UI and the effector - a shared secret would suffice - so that other programs on the system can't call the effector. Using a trust system which relies on challenge based auth or asymmetric encryption means that you no longer have to worry about the local connection constraint.
Finally, you need a well defined protocol by which the UI and effector communicate.
This is a lot more complex than using sudo, but is more secure (e.g. sudo just allows users to execute specific files as a different uid - you hope that the file contains the right program).
Setuid has many of the same drawbacks as sudo with the added complication that (in most cases) if it starts another program - then it will do so as the original uid.
HTH
C.
精彩评论