OpenSSH:防止 SSH_ORIGINAL_COMMAND 上的通配符

OpenSSH:防止 SSH_ORIGINAL_COMMAND 上的通配符

我有以下设置,我使用 OpenSSH 服务器远程启动某个命令ssh

我的authorized_keys文件有以下条目:

command="/path/to/script.sh $SSH_ORIGINAL_COMMAND",no-port-forwarding,no-x11-forwarding,no-agent-forwarding ssh-rsa AAAA…qGDf my_special_key

这意味着如果有人使用该密钥(例如通过使用ssh -i special_key_file user@server)连接,脚本script.sh将在我的服务器上执行。现在还有一个$SSH_ORIGINAL_COMMAND占位符,它被命令的所有额外命令行替换ssh,即ssh -i special_key_file user@server foobar意味着将在其中$1包含。foobar

为了测试它,我可以使我的script.sh外观如下:

#!/bin/sh
printf '<%s>\n' "$@"

现在ssh -i special_key_file user@server 'foo bar'就像 forssh -i special_key_file user@server foo bar我会得到以下相同的结果:

<foo>
<bar>

因为分裂。如果这还不够糟糕的话,因为ssh -i special_key_file user@server '*'我得到了一个文件列表:

<file1>
<file2>

因此,显然整个额外的命令行被插入到内部的内容中command=,然后在 shell 中运行,并发生所有拆分和全局步骤。显然我不能"在该command="…"部分内部使用,所以我不能$SSH_ORIGINAL_COMMAND在双引号内放入双引号以防止这种情况发生。我还有其他解决方案吗?

顺便说一句,正如本中所解释的驳回 RFE 引入 $SSH_ESCAPED_ORIGINAL_COMMANDssh协议是罪魁祸首,因为所有额外的命令行都作为一个字符串传输。尽管如此,这仍然没有理由让服务器端的 shell 执行所有拆分操作,特别是如果它还执行全局扩展(我怀疑这在这里​​是否有用)。与介绍 RFE 的人不同,我不关心用例的拆分,我只想要没有全局扩展。

可能的解决方案是否与更改 OpenSSH 用于此任务的 shell 环境有关?

答案1

使用引号:

cat bin/script.sh
#!/bin/sh
printf '<%s>\n' "$@"

command="/home/user/bin/script.sh \"${SSH_ORIGINAL_COMMAND}\"" ssh-rsa AA...

ssh -i .ssh/id_rsa.special hamilton '*'
<*>
ssh -i .ssh/id_rsa.special hamilton 'foo bar'
<foo bar>

但你也会得到:

ssh -i .ssh/id_rsa.special hamilton '*' 'foo bar'
<* foo bar>

不确定这对你来说是否是一个问题。

我很困惑:

显然我不能在命令中使用“=”…“

我认为这是你任务的限制,所以删除了我的答案。
我很高兴我的回答对您的任务有所帮助!

答案2

根本不需要将 $SSH_ORIGINAL_COMMAND 放在命令行上。它可作为 /path/to/script.sh 的环境变量使用。这将自动删除一层 shell 评估。

另外,如果您不希望 shell 扩展任何 glob 字符,请考虑使用某种不是 shell 的语言(例如 perl/python/ruby/等)编写 script.sh。非 shell 语言仅在明确指示时才执行 glob/文件扩展。但是,如果它直接从环境获取 $SSH_ORIGINAL_COMMAND 的值而不是通过命令行传递给它,则可能没有必要。

相关内容