OpenSSH:防止 SSH_ORIGINAL_COMMAND 上的通配符

phk*_*phk 7 openssh quoting wildcards

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

\n\n

我的authorized_keys文件有以下条目:

\n\n
command="/path/to/script.sh $SSH_ORIGINAL_COMMAND",no-port-forwarding,no-x11-forwarding,no-agent-forwarding ssh-rsa AAAA\xe2\x80\xa6qGDf my_special_key\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n
#!/bin/sh\nprintf \'<%s>\\n\' "$@"\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
<foo>\n<bar>\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
<file1>\n<file2>\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

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

\n

Fed*_*rev 5

使用引号:

\n\n
cat bin/script.sh\n#!/bin/sh\nprintf \'<%s>\\n\' "$@"\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
ssh -i .ssh/id_rsa.special hamilton \'*\'\n<*>\nssh -i .ssh/id_rsa.special hamilton \'foo bar\'\n<foo bar>\n
Run Code Online (Sandbox Code Playgroud)\n\n

但你也会得到:

\n\n
ssh -i .ssh/id_rsa.special hamilton \'*\' \'foo bar\'\n<* foo bar>\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

我很困惑:

\n\n
\n

显然我不能在命令中使用“=”\xe2\x80\xa6”

\n
\n\n

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

\n


raf*_*raf 5

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

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