Using CentOs, I want to run a script as user 'training' as a system service. I use daemontools to monitor the process, which needs a launcher script that is run as root and has no tty standard in.
Below I give my five different attempts which all fail.
:
#!/bin/bash exec >> /var/log/training_service.log 2>&1 setuidgid training training_command
This last line is not good enough since for training_command, we need environment for trqaining user to be set.
:
su - training -c 'training_command'
This looks like it (Run a shell script as a different user) but gives '
standard in must be tty
' as su making sure tty is present to potentially accept password. I know I could make this disappear by modifying /etc/sudoers (a la https://superuser.com/questions/119376/bash-su-script-giving-an-error-standard-in-must-be-a-tty) but i am reluctant and unsure of consequences.:
sudo -u training -i bash -c 'source $HOME/.bashrc; training_command'
A variation on the same theme: '
sudo: sorry, you must have a tty to run sudo
':
runuser - training -c 'training_command'
This one gives
runuser: cannot set groups: Connection refused
. I found no sense or resolution to this error.:
ssh -p100 training@localhost 'source $HOME/.bashrc; training_command'
This one is more of a joke to show desparation. Even this one fails with
Host key verification failed.
(the host key IS in known_hosts, etc).
Note: all of 2,3,4 work as they should if I run the wrapper script from a root shell. problems only occur if the system service monitor (daemontools) launches it (no tty terminal I guess).
I am stuck. Is this something so hard to achieve?
I appreciate all insight and guidance to best practice.
(this has also been posted on superuser: https://superuser.com/questions/434235/script-calling-script-as-other-user)
You will need to disable the
requiretty
setting in/etc/sudoers
forroot
. Add the following line viavisudo
:You will also need the following line in
/etc/sudoers
soroot
can do everything (this should be enabled by default, but check to be sure):Then you can do the following:
This seems to be essentially a special case of this question; we can use
script -c
to fake a tty. The only problem is that I can't get that trick to work directly withsu
for some reason, andsudo
is a bit ugly if you really have to source~/.bashrc
beforetraining_command
. Try:Choose the first one and set the environment variables you need.
If you already use daemontools then you do not create or mess with the log files manually. Daemontools does that job for you.
This is the script for the applicatoin run script
Then you create a
log
directory run script with its own runscript.Refer to this entry for setting up a log: http://cr.yp.to/daemontools/faq/create.html#runlog
Plagiarising my answer here: Starting a script as another user
You could use start-stop-daemon something like this:
where training.sh is something like this:
Under SSH, you can run command
foo.sh
in normal user:if one of
foo.sh
's command need root privilege, for example,netstat
, wrap it withinsu
command like this (replace original rawnetstat -tunple
):and run
foo.sh
like this:This will prompt tow password, the first is for
normal_user
, and the second is forroot
.Run your command with SSH.
make ssh key configuration to login without password for other user. Here is a tutorial for this purpose: https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
Run the command with ssh: ssh -l training -i key_file "training_command"
Try this:
If this fails, please post the output of /var/log/training_service.log.