我有一个 bash 脚本:
- 做某事
- 连接/打开反向 shell。
- 做另一件事
my-script
内容:
#!/usr/bin/env bash
# does 'some thing'
sudo /usr/bin/nsenter --setuid 1000 --setgid 1000 --net=/var/run/netns/ns-a -- socat file:$(tty),raw,echo=0 tcp:10.10.10.1:2222
# does 'another thing'
从终端交互运行此脚本停止并提供远程 shell 供用户交互。
用例是有一个脚本:
- 接受管道输入(例如 HEREDOC 样式)
- 当没有给出管道输入时,呈现一个交互式 shell。
我希望能够做的是在批处理文件(管道输入)中以及交互地使用此脚本。
以下内容让我难住了:
my-script <<EOCMDS
echo 1
echo 2
EOCMDS
2020/12/13 21:28:59 socat[28032] E exactly 2 addresses required (there are 4); use option "-h" for help
感谢您可能想到的任何解决方案。
更新:
这不是关于设置远程 shell 的问题。为了避免疑问,远程服务器已设置并侦听,准备在连接时提供 (bash) shell。这个问题仅涉及客户端。为了进一步消除疑问,虽然与这个问题无关,但实际上远程服务器不是网络命名空间的,只有本地客户端。
答案1
好吧,事实证明这并不是那么微不足道的事情。
用户输入时
$ wgsh
wgsh@vultr /$
和管道命令:
$ wgsh <<EOD
echo 1
echo 2
echo 3
EOD
虽然不容易,但还是可以做到的。
解决办法是让本地socat
打开远程shell(反向shell)。每当检测到管道命令输入时,就会进入后台。最后,将每个管道命令提交到/dev/ptsN
与后台关联的socat
。
第一个问题是socat
每当尝试后台时总是认为它有两个额外的参数在 shell 脚本中。抱怨:
socat[3124] E exactly 2 addresses required (there are 4)
第二个问题是在另一个人身上执行命令/dev/ptsN
并不简单。
因此,解决方案分为两部分:
- 用于
tmux
后台socat
连接。 - 用于
ttyecho
将每个管道命令发送到后台socat
.
ttyecho
是一个Pratik Sinha 的自定义实用程序,其中还有一个生锈的箱子。
该命令行工具在功能上与的一部分ttyecho
类似,但据我所知,该工具的开发已经停止,最后一个 Ubuntu 软件包适用于 12.04。writevt
console-tools
这意味着您很可能必须编译并安装您自己的ttyecho
.
还有一些额外的皱纹——不是一直都有吗?
打开新的 ttytmux
需要 root 权限。为了能够运行:
sudo --validate
tmux ...
如果没有启动的进程阻止密码,您需要添加到您的/etc/sudoers.d/<user>
:
Defaults: <user> !tty_tickets
一切就绪后,这应该可以工作(在ttyecho
您的路径中)
if [ -t 0 -a $# -eq 0 ]
then
## No piped commands.
## 1. Start interactive shell.
sudo /usr/bin/nsenter --setuid 1000 \
--setgid 1000 \
--net=/var/run/netns/nns-a \
-- \
socat file:$(tty),raw,echo=0 \
tcp:10.10.10.1:2222
else
## Piped commands.
## 1. Setup sudo --validate for new tty sessions:
# Add
# Defaults: <user> !tty_tickets
# to the file (chmod 440): /etc/sudoers.d/<user>
#
sudo --validate
## 2. Start a detached connection to remote shell.
#
tmux new-session \
-d \
-s a_session \
'sudo /usr/bin/nsenter --setuid 1000 --setgid 1000 --net=/var/run/netns/nns-a -- socat file:$(tty),raw,echo=0 tcp:10.10.10.1:2222'
## 3. Capture the socat process ID
#
SOCAT_PID=$(pgrep -u "root" socat)
## 4. Get the /dev/pts of the socat connection
#
DEV_PTS=$(tmux list-panes -t a_session -F '#{pane_tty}')
## 5. Consume all the piped commands
#
while read cmd
do
sudo /usr/bin/nsenter --setuid 1000 \
--setgid 1000 \
--net=/var/run/netns/nns-a \
-- \
ttyexec -n ${DEV_PTS} "${cmd}"
done
## 6. Exit, if not already done.
#
if pgrep -u "root" socat
then
sudo /usr/bin/nsenter --setuid 1000 \
--setgid 1000 \
--net=/var/run/netns/nns-a \
-- \
ttyexec -n ${DEV_PTS} "exit"
fi
fi
希望对某人有帮助吗?
答案2
对于反向 shell:
sudo /usr/bin/nsenter --setuid 1000 --setgid 1000 --net=/var/run/netns/ns-a -- socat TCP4:10.10.10.1:2222 EXEC:/bin/bash
然后在后台执行脚本:
./my-script &
另一方面 :
socat -d TCP4-LISTEN:2222 STDOUT
<commands to execute>