Running upstart jobs as unprivileged users

Solution 1:

With upstart v1.4, setuid and setgid are supported natively in config file.

Solution 2:

Asking on the #upstart channel on freenode, the official take on the matter is:

A future release of Upstart will have native support for that, but for now, you can use something like:

exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]

Solution 3:

How about using start-stop-daemon?

exec start-stop-daemon --start --chuid daemonuser --exec /bin/server_cmd

From Upstart cookbook:

The recommended method for Debian and Ubuntu systems is to use the helper utility start-stop-daemon. […] start-stop-daemon does not impose PAM ("Pluggable Authentication Module") limits to the process it starts.

Note: start-stop-daemon not supported in RHEL.

Solution 4:

There are several ways to do it, all with slightly different semantics, particularly relating to group membership:

  • setuidgid will put you in the group you specify.

    • The original daemontools' setuidgid will put you only in that group, so you won't be able to access files belonging to other groups you're a member of.
    • The setuidgid from daemontools-encore and the setuidgid from the nosh toolset both have an -s (a.k.a. --supplementary) option which will put you in that group, and also put you in all of the supplementary groups for the user that you specify.
  • Using newgrp once you've become the less privileged user will add a single group to your groupset, but also creates a new subshell, making it tricky to use inside scripts.

  • start-stop-daemon preserves your group membership, and does a whole lot more than just setuid/setgid.

  • chpst -u username:group1:group2:group3... commandname will let you specify exactly what group memberships to adopt, but (in Ubuntu) it only comes with the runit package, which is an alternative to upstart.

  • su -c commandname username picks up all of username's group memberships, as does sudo -u username commandname, so they're probably the route to least astonishment.

Solution 5:

Use setuidgid from the package daemontools.

Documentation here: http://cr.yp.to/daemontools/setuidgid.html