我有以下设置,我使用 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_COMMAND
该ssh
协议是罪魁祸首,因为所有额外的命令行都作为一个字符串传输。尽管如此,这仍然没有理由让服务器端的 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 的值而不是通过命令行传递给它,则可能没有必要。