How to run a command as a specific user in an init script?
Asked Answered
Q

6

40

I'm writing an init script which is supposed to execute a single command as a user different than root. This is how I'm doing it currently:
sudo -u username command

This generally works as expected on Ubuntu/Debian, but on RHEL the script which is executed as the command hangs.
Is there another way to run the command as another user?
(Note that I can't use lsb init functions as they're not available on RHEL/Centos 5.x.)

Quiescent answered 30/7, 2013 at 19:53 Comment(1)
Notice that this question is about something set up exclusively by the administrator (typically, a daemon that runs as some user for security). A slightly different case is users setting up on their own commands to run at boot, with their user crontab. See askubuntu.com/questions/260845/…Obnubilate
W
28

On RHEL systems, the /etc/rc.d/init.d/functions script is intended to provide similar to what you want. If you source that at the top of your init script, all of it's functions become available.

The specific function provided to help with this is daemon. If you are intending to use it to start a daemon-like program, a simple usage would be:

daemon --user=username command

If that is too heavy-handed for what you need, there is runuser (see man runuser for full info; some versions may need -u prior to the username):

/sbin/runuser username -s /bin/bash -c "command(s) to run as user username"
Weisburgh answered 24/7, 2015 at 17:38 Comment(4)
at least on RHEL6, runuser does not accept the -u parameter and one would run it just like this: runuser username -s /bin/bash -c "command"Precambrian
For Centos 7, also should not use -u or the command fails. And /sbin/runuser username -s /bin/bash -c "command" works.Polite
For anyone dealing with the error options --(shell,fast,command,session,session-command,login) and --user are mutually exclusive, the following format worked for me: runuser -u username -- commandMyrticemyrtie
Thanks @lagweezle, this seems like it will work for me for my starting of the command, what's the best way to stop that daemon? in the stop part of my init.d script?Miltiades
A
18

For systemd style init scripts it's really easy. You just add a User= in the [Service] section.

Here is an init script I use for qbittorrent-nox on CentOS 7:

[Unit]
Description=qbittorrent torrent server

[Service]
User=<username>
ExecStart=/usr/bin/qbittorrent-nox
Restart=on-abort

[Install]
WantedBy=multi-user.target
Autoerotic answered 25/10, 2014 at 17:43 Comment(2)
systemd may be controversial but this is certainly a nice convenience. I am going to do this for my (hashicorp) vault server process. thanks.Meditate
I don't really keep up with linux dev drama :) I have just found systemd easy to deal with since centos adopted it. I am never going back to the mess that preceded it :)Autoerotic
W
13

Instead of sudo, try

su - username command

In my experience, sudo is not always available on RHEL systems, but su is, because su is part of the coreutils package whereas sudo is in the sudo package.

Willed answered 30/7, 2013 at 22:1 Comment(4)
I tried this, but it requires a password for the service user, which I don't intend to ever set. sudo -u <username> <command> on the other hand, does not. Note that I run these with my user account, not a root account.Compact
sudo wont work if requiretty is set in /etc/sudoers (the default in cent 6, 7 and fedora 20).Hadfield
Same problem here, cant user su because it requires a password. So what is the best approach for this? Noone seems to have a proper answer :(Annetteannex
This is what worked for me on RHEL 6. I also used the -m flag to preserve environment variables: su -m username commandWoad
M
12

If you have start-stop-daemon

start-stop-daemon --start --quiet -u username -g usergroup --exec command ...
Mcmillin answered 30/7, 2013 at 20:10 Comment(4)
It's not available in RHEL 5.Quiescent
@Quiescent start-stop-daemon is a Debian-ism.Kinna
You can use daemon, as @Weisburgh pointed out in his/her answer. By the way, it should be the accepted answer.Imputation
-u/--user is for checking, you should add -c/--chuid: Change to this username/uid before starting the processDetoxify
B
2

I usually do it the way that you are doing it (i.e. sudo -u username command). But, there is also the 'djb' way to run a daemon with privileges of another user. See: http://thedjbway.b0llix.net/daemontools/uidgid.html

Bronder answered 30/7, 2013 at 20:2 Comment(0)
C
2

Adding this answer as I had to lookup multiple places to achieve my use case. I had a script that runs on startup. This script runs process as a specific (passwordless) user and is running on multiple linux flavors. Here are options on different flavors: (I have taken java as target process for example)

1. RHEL / CentOS 6:

source /etc/rc.d/init.d/functions
daemon --user=myUser $JAVA_HOME/bin/java

2. RHEL 7 / SUSE12 / other linux flavors where systemd is used:

In your systemd unit file add:

User=myUser

3. Suse 11:

/sbin/startproc -u myUser $JAVA_HOME/bin/java

Crave answered 9/12, 2019 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.