我将从本地机器发送一个字符串到远程 ssh 服务器。
用户在一个简单的监狱里,所以他不能执行命令、登录、在远程 bash 上做一些事情,他只能发送一个字符串/值/变量并run
在 ssh 服务器上执行脚本。
这是用户的简单监狱
这是 USER 登录和运行 shell 的默认设置:
chsh -s /bin/bash [USER]
但是我将设置更改为这个简单的监狱:
chsh -s /home/[USER]/./run [USER]
ssh 服务器接收字符串并将字符串更改为新结果。
我将这个新结果保存在本地机器上一个名为OUTPUT
.
尝试后我找到了这个解决方案,称它为 hack 或 bug,但我不知道这是否是正确的方法!
- 使用此命令,我使用没有密码的 ssh 密钥 ssh 到远程服务器。
我在本地机器上的 SSH 命令连接到服务器:
ssh -i [KEY] -p [XXXX] [USER]@[HOST] '123' <<< "$VALUE" > OUTPUT
- 脚本从变量
run
接收字符串123
$VALUE
run
我在 SSH 服务器上的名字脚本
#!/bin/bash
echo "WELCOME TO SSH"
read VALUE
echo $VALUE
这只是一个例子,看看我的意思,真正的脚本生成一个哈希。
- 在我的本地机器上,我将远程 ssh 服务器
OUTPUT
脚本中的结果存储/保存在我的文件中。run
我的本地文件OUTPUT
与来自服务器的结果
WELCOME TO SSH
123
该read VALUE
命令在没有提示的情况下将值保存123
在变量中$VALUE
,并将结果保存在我的本地计算机上。
执行步骤:
- 连接到 ssh 服务器
- 从我的本地机器发送一个字符串到远程 ssh 服务器
- 远程服务器将此字符串更改为新结果
- 将本地计算机上的新结果保存在文件中
当我启动 ssh 命令时,它会打开连接,
脚本有效,我WELCOME TO SSH
在终端上看到
我在本地机器上收到结果并关闭连接。
您可以在您的机器上轻松测试此示例以了解我的意思。
这正是我需要的,但我想知道:
为什么我需要read
为什么我没有得到提示。
此示例的其他解决方案是什么。
如何通过 ssh 将字符串发送到服务器上的脚本,并使用被监禁的用户将服务器上的结果保存在本地计算机上的文件中?
更新解决方案
从@ilkkachu 回答我可以运行这个命令并发送:
字符串和变量:
ssh -i [KEY] -p [XXXX] [USER]@[HOST] "123" "$VALUE" > OUTPUT
细绳:
ssh -i [KEY] -p [XXXX] [USER]@[HOST] "123"> OUTPUT
多变的:
ssh -i [KEY] -p [XXXX] [USER]@[HOST] "$VALUE" > OUTPUT
没有什么:
ssh -i [KEY] -p [XXXX] [USER]@[HOST] > OUTPUT
#!/bin/bash
value= # empty by default
if [ "$1" = -c ]; then
value="$2"
fi
if [ -z "$value" ]; then
echo "value is empty" >&2
exit 1
fi
# do something with the value
echo "$value" | rev
SSH authorized_keys 命令选项
从这篇文章:
SSH authorized_keys 命令选项:多个命令?
不,这不是“允许”命令,而是“强制”命令(作为 ForceCommand 选项)。唯一的可能性是对不同的命令使用不同的键或从标准输入读取参数。
这是一个很好的提示,但对于单个命令,例如备份或输出一些信息。
如果我运行类似的命令rsync
,如果我不想收到错误,我必须做更多的配置。
所以我会和一个简单的被监禁用户和一个给定的脚本呆在一起。
使用与使用
ssh user@somehost <<< "$value"
几乎相同echo "$value" | ssh user@somehost
:将变量的内容发送到 SSH 客户端进程的标准输入。SSH 将其传输到远程端,远程进程可以在此处再次在标准输入上读取它。例如使用 shell 的read
,就像你在那里做的那样。这是通过 SSH 连接传递数据的一种方式。另一种方法是使用命令行参数。如果你跑
然后 SSH 要求远程端使用两个参数运行远程用户的 shell
-c
和some string here
. 使用普通的外壳程序,外壳程序会将“此处的某些字符串”解释为外壳程序命令行,因此确实ssh user@somehost "ls /tmp"
可以运行ls
. (ssh user@somehost ls /tmp
同样,SSH 客户端在将 args 发送到远程之前将它们与空格连接。)但是您更改了用户的 shell 以限制他们可以执行的操作,因此该
-c
选项不会执行 SSH 假定的操作。出于同样的原因,没有提示:您的脚本不会像普通 shell 那样打印一个。但是,将脚本作为外壳并不重要,因为它可以检测并忽略该
-c
选项并使用它之后的内容。例如,您可以在遥控器上有这样的脚本:
模拟示例将通过 传递值
rev
,反转字符串。因此,运行
ssh user@somehost "hello there"
会返回字符串ereht olleh
。运行 just
ssh user@somehost
,最后没有“命令”,会触发脚本中的错误消息,但它也会让 SSH 像启动交互式会话一样运行。它会在远程保留伪终端(pty),并且可能会运行一些通常在登录期间完成的额外内容,例如在 Linux 上运行 PAM 会话模块。那些做诸如打印“每日消息”或检查帐户是否有未读电子邮件之类的事情。与 相同ssh user@somehost ""
,因此您不能真正传递一个空参数并期望它的行为与非空参数完全相同。除了限制远程用户的 shell,另一种锁定可以通过 SSH 运行的命令的方法是使用 SSH 密钥,并使用
command=...
inauthorized_keys
. 这样做还允许使用no-pty
关键字禁用 pty 分配。(并且仅运行与密钥相关的强制命令这一事实可能会影响运行那些 PAM 会话模块。)请参阅 sshd手册页。我觉得你越来越糊涂了。
你最初问的是:
当你有一个本地值(例如
VALUE="XXXXXXXX"
在本地机器上)时,你可以将它保存到本地文件OUTPUT
而无需转到远程机器。您实际上想问的问题:
可能性 1:我认为,您想要一个远程值(例如
VALUE="XXXXXXXX"
在远程机器上),您想要将其保存到本地文件OUTPUT
中。解决方案 1:
注意:单引号,不是双引号!
在这里,单引号确保
VALUE
不在本地计算机上评估,而是在远程计算机上评估。您实际上想问的是:
可能性 2:“我想将值 VALUE 发送到在远程机器上运行的脚本,该脚本将输出一些新值;我希望在本地文件 OUTPUT 中使用该新值”
解决方案 2:
注意:双引号,不是单引号!
在这里,我们通过命令行参数将 VALUE 传递给您的脚本。在 /path/to/myscript 中,您可以通过 $1 访问该值,例如:
您实际上想问的是:
可能性 3:“我有一台远程机器,用户只能登录,执行预定义脚本 (
/home/[USER]/./run
) 并退出。我想向远程机器上运行的脚本发送一个值 VALUE,它将输出一些新值;我想要本地文件输出中的新值”解决方案 3:
注意:双引号,不是单引号!
在这里,我们通过命令行参数将字符串“MYVALUE”和变量 VALUE 的值传递给您的脚本。在您的 Script
/home/[USER]/./run
中,您可以通过 $1、$2、$2 等访问这些命令行参数值:在这里,我将回显所有命令行参数值 $1、$2、$3、$4、$5、$6、$7、$8、$9,以检查哪个具有 STRING MYVALUE 以及哪个具有变量 VALUE 的值。
当您发现例如 $3 具有正确的值时,删除所有不需要的
echo
行,取消注释最后 3 行,更新 N & M 并检查 ; 它应该工作!