强制SSH使用特定的Shell


29

有什么方法可以强制SSH在远程端使用特定的Shell,而不管用户的默认Shell是什么?

我尝试过类似的解决方案:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

但是不幸的是,远程端的默认Shell负责解析“复杂的多行命令”部分,而我很难对其进行足够的转义以使其同时适用于Bash和C Shell用户。


Answers:


8

我不相信这是不可能的,至少在基于opensh的系统上是不可能的。如果有能力,更好的解决方案可能是sftp一个shell脚本文件,然后使用您发布的方法执行它。这样做的好处是可以最大程度地减少所需的转义,但是会留下一个必须删除的文件(也许是脚本的最后一步)。


1
这是我最终所做的,但是使用了scp。好主意。
plinehan'7

16

使用heredoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF

您不应该在bash中使用“ -s”来读取来自stdin的命令吗?
Weboide

并非总是必需的。
伊格纳西奥·巴斯克斯

如果可以的话,我将其否决,因为它会阻止命令访问stdin,并且问题是有关调用特定的shell。
埃里克·伍德拉夫

3
@EricWoodruff,...调用特定的外壳程序(在本例中为bash)正好说明了该如何做。
查尔斯·达菲

1
仅供参考,您也可以这样做cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash。因此,您无需执行两个步骤,而是执行两个步骤:步骤1将脚本复制到文件中,步骤2 cat将脚本复制到中ssh
Trevor Boyd Smith,

10

使用基于密钥的登录名,而不是基于密码的登录名。然后,您可以将(强制列表)(强制列表)添加到安装在服务器上的SSH1 公用密钥(在SSH1情况下,在“选项”字段中)(在SSH1的〜/ .ssh / authorized_keys文件中) ,〜/ .ssh2 / SSH2 授权)。

进行强制命令,以便调用所需的shell ...

更多:您最多可以将一个强制命令与给定键关联。如果出于不同目的需要多个强制命令,则必须设置不同的键。(当然,您可以将多个内容放到一个脚本中,通过强制命令调用。但是要注意,如果用户登录,则强制命令始终针对给定的帐户/密钥运行,无论用户是否要求运行其他命令。如果您仍要遵守要求的原始命令,请查看如何利用该$SSH_ORIGINAL_COMMAND变量...)

通过Google阅读有关“强制命令”的信息。


好东西。O'Reilly页面上的图形非常好。但是,在我的特定情况下,我希望能够对所有用户强制执行此操作,而不仅仅是对正确设置密钥的用户。我在服务器计算机上也没有root用户,因此我无法编辑/etc/sshrc
plinehan

好吧,当您连接到服务器的服务时,总是由服务器(或者更好的是:对服务器施加控制的服务器)来做主。...服务器的“所有者”决定可以使用该服务器做什么。-如果您没有比他们更高的特权,则不能“对任何用户”强制执行任何操作。
Kurt Pfeifle

如果客户端可以运行任意命令,那么客户端也可以作为命令运行任意外壳。
埃里克·伍德拉夫

链接到O'Reilly的@KurtPfeifle已损坏
Brian Vandenberg

@BrianVandenberg:提示。我现在删除了该链接。
Kurt Pfeifle 2015年

2

您可以使用该-t选项为要启动的程序强制分配伪tty,就像执行标准Shell一样。然后将您想要的外壳作为普通的旧参数传递。

使用这种技术,您不仅可以使用已安装的任何shell,还可以通过一个命令打开vim和其他需要TTY的程序。如果您正在编写将您登录到某个地方并在vim或htop或其他文件上打开文件的shell脚本,那么这很酷。

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

不确定这是否是登录shell,但是是否存在使bash像登录shell一样的选项,因此您的shell也可能具有该功能。


1

令人惊讶的是,我看到以下结果:

在破折号中运行:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

vs bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

显示全引号的命令按预期工作。


1
一点也不奇怪。远程ssh守护程序有效运行sh -c "$*"。因此,您正在跑步sh -c "/bin/bash -c echo <(cat)";该echo命令本身是传递给的唯一参数-c,并且<(cat)是一个单独的参数。
查尔斯·达菲

0

不久前,我遇到了类似的情况,我需要对SQLplus使用ksh协同处理,而我只有一个ssh,必须通过该ssh进行读写。

一种方法是将所有从属命令通过管道传送到远程计算机上的/ usr / bin / ksh(使用;)。例如:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.