1

I have some users on my machine that I allow to run small Mumble voice servers. I would like for them to be able to start/stop their voice server from a website (being ran by Apache). With the current set up, I have each server being run as a different user (the person's specific user account).

What I can't figure out is the best way to start/stop the server without delay. Currently, I have the website make an entry into a database whenever they want to start/stop their service. Then, I have a cron script that runs every minute look in the database for these starts/stops. That cron script will switch to the users account and run the server as that user. My issue with this is that it can take up to around 1 minute for the action to happen.

Is there a more responsive way to accomplish this?

1
  • Is it really needed to start/stop the services? A service that is not used doesn't use much resources... Commented May 22, 2012 at 14:58

6 Answers 6

3

Instead of, or in addition to, writing to a database, have you considered writing to a named pipe? You could create one named pipe per user and then create a process to watch each named pipe. When the 'restart' command comes, immediately restart the process.

This is not a complete solution and can be improved upon, but it should give you an idea of how you could monitor the named pipe and restart the process.

while read line <$pipe
 do
  if [[ "$line" == 'restart' ]]; then
    restart_some_service
  fi
done
2
  • do you need a sleep in there, or will the absence of data on the named-pipe not consume system CPU? Commented May 23, 2012 at 0:10
  • 1
    pipe reads will be blocking, so no CPU consumption when no data is available, @shellter. Commented May 23, 2012 at 5:24
1

This might be overkill, but have you considered Usermin? They list a process plugin in the standard plugins, that lets your users

View all processes running on the system, kill those belonging to [them], and start new ones.

(Never tried this, just thought it might be pretty, uhm, "professional".)

(Edit Concerning "Mumble", there seem to be some web interfaces already, but I have no idea if they help in your situation.)

1

If these people you are hosting servers for are trustworthy and wont spam/hack the server, why not just program the web interface to directly pass the start/stop to the shell

For example, in PHP you could program this into the page:

<?php
  // checks, templating, blah, blah, blah
  $status = exec('/path/to/service/mumbled status')

  if ($status == "stopped")
    // display start button, hook exec('mumbled stop') command to it

  if ($status == "running")
    // display stop button, hook exec('mumbled start') command to it
?>

If it was me I would go that route, but that's just me.

2
  • 1
    One of the downsides of this method is that your mumbled and httpd will have to be run as the same user. Commented May 24, 2012 at 6:57
  • good point. that can be super disorganizing too. Commented May 26, 2012 at 4:37
0

I set up something like this on one of my webservers that had a problem of sshd dying occasionally -- I wanted to manually restart sshd from an authenticated web interface. This was intended (in my case) to be a short-term solution, as a full OS upgrade was not too far off anyway.

I set up a php page similar to what nonplus suggested, using shell_exec to execute a specific command via sudo:

  $output = shell_exec("/usr/local/bin/sudo /usr/local/etc/rc.d/sshd.sh restart");
  echo "<pre>$output</pre>";

This way, I could edit the local sudoers file to give my apache user the appropriate access to specific commands. I needed to grant it the root-level privilege of starting sshd; you could limit it to starting/stopping the appropriate services as the appropriate users.

0

Your cron method is the on the right track.. most other methods have various security concerns. To make that same idea faster, you could touch a file, and use inotify to detect that it was modified. inotify is extraordinarily fast. 'inotify-tools' is a readily available set of commandline tools that use inotify. There are some good examples on the github site for inotify-tools.

From: https://github.com/rvoicilas/inotify-tools/wiki/#wiki-info

#!/bin/sh
EVENT=$(inotifywait --format '%e' ~/file1)
[ $? != 0 ] && exit
[ "$EVENT" = "MODIFY" ] && echo 'file modified!'
[ "$EVENT" = "DELETE_SELF" ] && echo 'file deleted!'

It is basically instant - inotify is a kernel feature that these tools take advantage of which requests of the kernel notification on very specific file system events.

0

It is possible to let httpd (or any other user) be able to issue a specific command or run any specific service as any other (system)user without actually having sudo privileges.

In this case, assume apache runs with the www-data account:

In order to do this on Ubuntu do the following:
$ sudo vi /etc/sudoers.d/www-data
www-data ALL=(ALL) NOPASSWD: /usr/bin/crontab, NOPASSWD: /usr/bin/whoami, NOPASSWD: /bin/bash /home/steam/webstart.sh [[\:alpha\:]]*

Explanation:
What this does is create a file named www-data in the /etc/sudoers.d location. The file says that the www-data user is allowed, and ONLY allowed, to run "/usr/bin/crontab", "/usr/bin/whoami" and "/bin/bash /home/steam/webstart.sh" with sudo.

This means, that www-data can sudo start webstart.sh, which contains a script that in turn will start a service. This will run under the "steam" user account, and you don't need to give root privileges to the service.

-rwxrwxr-x 1 steam steam 123 Feb 15 14:52 webstart.sh

Note:
[[\:alpha\:]]* means that the webstart.sh command can be followed by any alphabetical letter, so you can pass arguments to the script. Without this, www-data would not even be allowed to run "/bin/bash /home/steam/webstart.sh a" as this is NOT what was specified. The sudoers is VERY strict and literal. If you want, you can specify exactly which command is allowed. If multiple commands are specifically allowed, you must add multiple statements seperated by comma's: NOPASSWD: /bin/bash /home/steam/webstart.sh start, NOPASSWD: /bin/bash /home/steam/webstart.sh stop, NOPASSWD: /bin/bash /home/steam/webstart.sh restart

Warning: Make sure NOT to add NOPASSWD: /bin/bash [[\:alpha\:]]* without specifying a command or script before the regex, as this would allow www-data to run /bin/bash followed by ANY command, obviously.

PS: It is not necesarry to actually name the file www-data, but I like to make a separate file for each user which I grant special privileges instead of combining them all into one.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.