Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

What's the canonical way to have an upstart job change its userid and run the script as an unprivileged user?

Obviously one can use su or sudo, but this seems hacky (and can generate needless log lines).

share|improve this question

migrated from stackoverflow.com Nov 21 '10 at 13:42

This question came from our site for professional and enthusiast programmers.

add comment

7 Answers

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...]
share|improve this answer
2  
This is the only answer that worked on Amazon Linue EC2 (I tried all variations of sudo and su, including --session-command, -c, ad nauseum); none of them allowed the process to be stopped once started; thanks so much for this. –  Kato Dec 2 '11 at 10:42
add comment

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

share|improve this answer
    
The best answer. –  Andrey Regentov Oct 19 '12 at 4:56
3  
See the cookbook for specifics on this: upstart.ubuntu.com/cookbook/#run-a-job-as-a-different-user –  Jason Navarrete Oct 25 '12 at 16:32
4  
In other words, it's supported in Precise (12.04) and newer. –  nilbus Jan 19 '13 at 3:24
    
In other words, is not supported in centos 6 –  socketpair Dec 26 '13 at 6:43
    
Best answer if you have Upstart >= 1.4. You should bookmark the 'su' solution though as it can be handy when you need it. –  tiktak 2 days ago
add comment

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.

share|improve this answer
    
You can also use the group, if you need it. With --chuid daemonuser:daemongroup –  Evgeny May 30 '11 at 15:33
add comment

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

  • setuidgid will put you in only the group you specify, so you won't be able to access files belonging to other groups you're a member of unless you use newgrp.

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

share|improve this answer
add comment

Use setuidgid from the package daemontools.

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

share|improve this answer
7  
daemontools isn't a prerequisite of upstart, so this doesn't seem like the 'canonical' answer –  Adam Nelson Jan 8 '10 at 21:52
2  
Further, daemontools is in universe (ubuntu 10.04), and upstart is in main. –  jtimberman Aug 14 '10 at 18:18
add comment

On an Ubuntu 10.10 instance on Amazon EC2, I had better luck with the start-stop-daemon command.

I also struggled with some of the other upstart stanzas. I am calling a python application with a specific virtualenv and some parameters to my executed program.

The following is what worked for me.

script
  export PYTHONPATH=.:/home/ubuntu/.local/lib/python2.7/site-packages/:/home/ubuntu/python/lib/python2.7/site-packages/
  exec start-stop-daemon --start  --chuid ubuntu --exec /home/ubuntu/python_envs/MyProj/bin/python /home/ubuntu/www/MyProj/MyProj.py -- --config-file-dir=/home/ubuntu/www/MyProj/config/ >> /home/ubuntu/startup.log 2>&1 &
end script

The PYTHONPATH is to get some packages installed from source into the PYTHON module path when this upstart job runs. I had to do everything in absolute paths because the chdir stanza didn't seem to do work.

share|improve this answer
    
I have also had problems with env variables used with exec start-stop-daemon. –  Thomas Bratt Aug 6 '13 at 11:30
add comment

There is a third possibility depending on what you are trying to accomplish. You may be able to loosen the access controls on the files/devices in question. This can allow an unprivileged user to mount or access items that they normally wouldn't. Just be sure you aren't giving away the keys to the kingdom in the process.

You can also change the timeout of the sudo password cache. But I don't recommend it unless your machine is physically secure. (i.e. You believe that it's unlikely that a passer-by would attempt to gain sudo access.)

There's a good reason that there are very few ways to perform privileged actions and that they perform -n-e-e-d-l-e-s-s- necessary logging. Loose restrictions would be a security hazard for your system and a lack of logging would mean there's no way to know what happened when you've been compromised.

If the size of your log files is a concern then something is probably wrong. Sudo only generates one line per use under normal conditions.

share|improve this answer
add comment

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.