SSH 进入一个盒子,立即后台进程,然后在 bash 脚本中以原始用户身份继续

SSH into a box, immediately background the process, then continue as the original user in a bash script

我需要编写一种方法来执行以下操作(请注意,所有操作均以 root 用户身份在本地计算机上完成):

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

第一个命令应该是 运行 作为 root。最终目标是以“user1”身份登录,这样如果有任何用户运行 who,“user1”就会出现在这个列表中。注意第一个命令是如何在下一个命令 运行 之前背景化的。 下一个命令也应该是 运行 作为 root,而不是 user1.

问题:这些命令 运行 在单独 运行 时很好,但是当 运行 在脚本“user1”中 运行 时从未出现 运行ning who。这是我的脚本

#!/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>/dev/null
echo "[+] Done."

当 运行 运行脚本时,脚本似乎能够通过 ssh 进入系统,但 who 不显示用户登录,也不显示任何 ps aux 输出一个 ssh 会话。注意:我注释掉了 kill 行以确认进程是否保留,但我根本看不到它。 如何使 bash 脚本分叉两个进程。流程 1 的目标是以“user1”身份登录并等待。那么进程2是在user1登录的情况下以root身份执行命令?

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?

有了这些附加信息,问题基本上可以归结为“我如何启动和后台 interactive ssh 会话?”。

您可以使用 script。它可以用来诱使应用程序认为它们正在 运行 交互:

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

OP 提供更多详细信息之前的原始答案(供将来参考):


让我们来剖析一下这里发生了什么。

我假设您以 root 身份启动脚本:

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

所以 root 运行s runuser -l user1 -c '...',它本身 运行s ssh -q localhost 2>/dev/null 作为 user1。由于 &.

所有这一切都发生在后台

ssh 将打印 Pseudo-terminal will not be allocated because stdin is not a terminal.(由于 2>/dev/null 而隐藏)并立即退出。这就是为什么当 运行ning who 或 运行ning ps.

时你看不到任何东西的原因

你的 echo[+] 成为用户 1,这与实际情况完全不同。

sleep 1

脚本休眠一秒钟。没有错。

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'

忽略打字错误,再次 root 运行s runuser,这次 运行s systemctl --user list-units 作为 user1

你的 echo[+] 运行 systemctl --user commands as root.,但实际上你是 运行ning systemctl --user list-unitsuser1 如上所述。

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

这会终止在脚本开头启动的 ssh 进程,但它已经退出,所以这什么都不做。作为旁注,这可以更容易地完成:

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

所以这应该可以让您更好地理解脚本的实际作用,但是在您描述的目标和脚本中相互冲突的 echo 之间,很难弄清楚它应该在哪里去。