如何使用authorized_keys文件中的“command”选项来保护ssh密钥而不使用密码?

有时候使用带有空密码的ssh密钥是非常可取的(备份,…)。 众所周知的问题是,这样的钥匙是安全的,只能保持不受信任的手。

但是,如果这些密钥被泄露,那么可以通过在服务器authorized_keys文件中添加一些选项来进一步保护这些密钥免受太多的伤害,例如:

 command="/usr/bin/foo",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAA..... 

理论上,这个键只能用来在服务器上运行命令/usr/bin/foo 。 出现一个新的问题,因为每个命令都需要一个特殊的专用密钥。

由于这个原因,可以在因特网上find更详细的变体(例如,在这个同一个站点: sshd_config与authorized_keys命令参数 ),其中包括安装一个通用键,该通用键限制在本地制作的脚本中,该脚本将使用SSH_ORIGINAL_COMMAND环境variables由ssh设置。

authorized_keys的(限制)键blurb将如下所示:

 command="/usr/local/bin/myssh",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAA..... 

myssh脚本看起来像:

 #!/bin/sh msg="Command not allowed with this key" case "$SSH_ORIGINAL_COMMAND" in *\&*) echo $msg ;; *\(*) echo $msg ;; *\{*) echo $msg ;; *\;*) echo $msg ;; *\<*) echo $msg ;; *\`*) echo $msg ;; *\|*) echo $msg ;; rsync\ --server*) # optionnally check for extra arguments # .... # then $SSH_ORIGINAL_COMMAND ;; some-local-script*) # optionnally check for extra arguments # .... # then $SSH_ORIGINAL_COMMAND ;; *) echo $msg ;; esac 

我唯一的问题是:能否确定这样一个被保护的钥匙不能用来逃离笼子

提前致谢 !

实际上,gitolite使用相同的方法来validation用户(在使用的SSH密钥上标识用户基础)并限制用户可以运行的内容(实际上只有启动gitolite的命令)。

gitolite被kernel.org用于访问控制他们的git repo,所以我认为这个方法应该是相当可靠的。 1

这取决于包装脚本和允许的命令的安全性。

包装脚本需要防止尝试运行多个命令(例如allowed-command blah; other-command )或滥用PATH差异。 我可能会编写脚本以完整path调用允许的命令,并使用exec来阻止对客户端提供的命令的进一步解释:

 set -- $SSH_ORIGINAL_COMMAND case "$SSH_ORIGINAL_COMMAND" in rsync\ --server*) shift 2; exec /usr/bin/rsync --server "$@" ;; 

您还需要确保允许的命令没有执行其他命令的机制。 例如, rsync -e "other-command"会使rsync执行一个不同的命令。 ( --server应该防止在上面的脚本中。)

我不是ssh或者安全专家,但是除了ssh或者你的'myssh'脚本中的某种错误,我看不到任何安全问题。 但是你知道那个古老的谚语,比遗憾更安全。 也许你也可以configuration基于IP的过滤,如果适用的话。