Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I was thinking of building a F/OSS project as a cPanel for Ubuntu Server, since Ubuntu doesn't have this, and yet making it easy for a hosting company to use this, where users will find it just as intuitive as cPanel.

Trouble is, PHP web pages on Ubuntu run as www-data, and lots of senior PHP guys recommend not running a PHP page as root, and not shelling out and running a Bash script that may have a sticky bit applied on its permissions. They say that's a way to get hacked.

It then dawned on me how to get around this. Make a Bash script daemon in /etc/init.d that watches a named pipe connection, sitting in a loop. The loop will hang, but that's perfectly okay because it will be in the background, and in a sense it means that the script is dormant and not soaking up CPU cycles. That's cool! It's certainly better than a sleep loop, and means the process only wakes up when there's something that needs to be processed. The sleep loop technique, on the other hand, may be checking for PHP communication when there may not be any, and so the sleep loop soaks up unnecessary CPU. That's why I like the pipe-wait-loop strategy.

So, then all the PHP page has to do is do normal file I/O to like /tmp/pipe (my pipe, for instance) and the Bash script daemon in the background will wake up out of dormancy in that loop, and process a command as root. It can look in a database for new things it needs to do, and then do those tasks. When done, it can return values to the database and the PHP page can wait in a jQuery/AJAX loop until it receives a response back.

Because the PHP page doesn't actually compose the root commands it needs to run, and merely writes some records to a database table, and sends a string of "run" to the pipe, it safely passes on a request to the secure daemon in the background.

What do you think of this IPC technique? Good? Bad?

BTW, my demo /usr/sbin/foo command looks like this. Its point is to demonstrate that /tmp/foo-was-here was created by the root user account, triggered by a PHP page. It's just the start of something bigger.

#!/bin/bash

if [ ! -f /tmp/foo ]; then
    mkfifo /tmp/foo
fi

while true; do
    cat /tmp/foo;
    touch '/tmp/foo-was-here';
done
share|improve this question

1 Answer 1

I'd say: go run a gearman daemon as the correct user, and set some gearman workers as priviliged users up with something like supervisord. Both are in the Debian packages, so I assume they'll be in the Ubuntu packages also....

Do set up gearman with a maximum number of tries, or you could encounter a Poison Message problem.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.