views:

83

answers:

3

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 this. 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?

+2  A: 

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.

timdev
The only problem with this is: 1) I need the accounts created immediately, I can't wait for cron... which leads to 2) I don't want to be running cron every minute, won't that put a lot of strain on the server?
jtd
Which is why the other option is to write a daemon (background process) that watches the queue and performs actions immediately. As long as you're not using shared hosting (and it sounds like you're not if you're adding users), this is probably feasible.
Tyler McHenry
Right, there are a number of ways to go at it. An every-minute cron would be fine, if it's acceptable to wait up to one minute. It won't put any appreciable load on the server -- most of the time, it would just see the queue is empty and exit. I'd probably just write a little daemon that checks the queue every second or so. For your purposes, a single-processes, non-threaded daemon should suffice. The only downside is you now need to make sure your daemon is always running -- but that's pretty easily solvable.
timdev
An even more efficient way to write the daemon would to be to set up the queue as a named pipe and have the daemon `select` on the pipe's file descriptor. That way it would only ever run when there is data to read from the queue, and it would run almost immediately when new data appears.
Tyler McHenry
+1  A: 

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) .

Shin
A: 

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.

symcbean