Home > Enterprise >  SSH into a box, immediately background the process, then continue as the original user in a bash scr
SSH into a box, immediately background the process, then continue as the original user in a bash scr

Time:10-20

I need to script a way to do the following (note all is done on the local machine as root):

runuser -l user1 -c 'ssh localhost' &
runuser -l user1 -c 'systemctl --user list-units'

The first command should be run as root. The end goal is to log in as "user1" so that if any user ran who "user1" will appear in this list. Noticed how the first command is backgrounded before the next command is run. The next command should be run as root as well, NOT user1.

Problem: These commands run fine when run separately, but when run in a script "user1" never appears to show up when running who. Here is my script

#!/bin/bash
echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
echo
sleep 1
echo "[ ] Running systemctl --user commands as root."
runuser -l user 1 -c 'systemctl --user list-units'
echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null
echo "[ ] Done."

When running the script it looks like the script is able to ssh into the system but who does not show the user logged in, nor do any ps aux output show a ssh session. Note: I commented out the kill line to confirm if the process stays, which I do not see it at all. How do I make the bash script fork two processes. Process 1 goal is to login as "user1" and wait. Then process 2 is to perform commands as root while user1 is logged in?

CodePudding user response:

My goal is to run systemctl --user commands as root via script. If your familiar with systemctl --user domain, there is no way to manage systemctl --user units, without the user being logged in via traditional methods (ssh, direct terminal, or gui). I cannot "su - user1" as root either. So I want to force an ssh session as root to the vdns11 user via runuser commands. Once the user is authenticated and shows up via who I can run systemctl --user commands. How can I keep the ssh session active in my code?

With this additional info, the question essentially boils down to 'How can I start and background an interactive ssh session?'.

You could use script for that. It can be used to trick applications into thinking they are being run interactively:

echo "[ ] Starting SSH session in background"
runuser -l user1 -c "script -c 'ssh localhost'" &>/dev/null &
pid=$!
...
echo "[ ] Killing active SSH session"
kill ${pid}

Original answer before OP provided additional details (for future reference):


Let's dissect what is going on here.

I assume you start your script as root:

echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &

So root runs runuser -l user1 -c '...', which itself runs ssh -q localhost 2>/dev/null as user1. All this takes place in the background due to &.

ssh will print Pseudo-terminal will not be allocated because stdin is not a terminal. (hidden due to 2>/dev/null) and immediately exit. That's why you don't see anything when running who or when running ps.

Your echo says [ ] Becoming user1, which is quite different from what's happening.

sleep 1

The script sleeps for a second. Nothing wrong with that.

echo "[ ] Running systemctl --user commands as root."
#runuser -l user 1 -c 'systemctl --user list-units'
#               ^ typo!
runuser -l user1 -c 'systemctl --user list-units'

Ignoring the typo, root again runs runuser, which itself runs systemctl --user list-units as user1 this time.

Your echo says [ ] Running systemctl --user commands as root., but actually you are running systemctl --user list-units as user1 as explained above.

echo "[ ] Killing active ssh sessions."
kill $(ps aux | grep ssh | grep "^user1.*" | grep localhost | awk '{print$2}') 2>/dev/null

This would kill the ssh process that had been started at the beginning of the script, but it already exited, so this does nothing. As a side note, this could be accomplished a lot easier:

echo "[ ] Becoming user1"
runuser -l user1 -c 'ssh -q localhost 2>/dev/null' &
pid=$!
...
echo "[ ] Killing active ssh sessions."
kill $(pgrep -P $pid)

So this should give you a better understanding about what the script actually does, but between the goals you described and the conflicting echos within the script it's really hard to figure out where this is supposed to be going.

  • Related