【发布时间】:2011-09-20 18:52:15
【问题描述】:
我需要将一些文件从服务器 A 部署到服务器 B。我通过 SSH 连接到服务器 A,然后从那里通过 ssh 连接到服务器 B,使用存储在服务器 A 上的私钥,其中的公钥位于在服务器 B 的授权密钥文件中。从 A 到 B 的连接发生在服务器 A 上的 Bash shell 脚本中。
这一切都很好,很好,很简单,直到有安全意识的管理员指出我存储在服务器 A 上的 SSH 私钥没有密码保护,所以任何可能侵入我在服务器 A 上的帐户的人也会有访问服务器 B,以及 C、D、E、F 和 G。我猜他说得有道理。
他提出了一个复杂的场景,在这个场景下我会添加一个密码,然后修改我的 shell 脚本,在开头添加一行,我会在其中调用
ssh-keygen -p -f {private key file}
用密码回答我的旧密码的提示和(两个)提示我的新密码的提示,只需返回即可摆脱密码,然后在最后,在我的 scp 命令之后 调用
ssh-keygen -p -f {private key file}
再次,把密码短语放回去
我说“Yecch!”。
好吧,我可以通过先阅读脚本中的密码短语来稍微改进一下
read -s PASS_PHRASE
然后根据需要使用 ssh-keygen 的 -N 和 -P 参数提供它。
它几乎可以使用,但我讨厌 shell 脚本中的交互式提示。我想把它归结为一个交互式提示,但让我感到难过的部分是我必须按两次回车键才能摆脱密码短语的部分
这可以从命令行工作:
ssh-keygen -p -f {private key file} -P {pass phrase} -N ''
但不是来自 shell 脚本。在那里,似乎我必须删除 -N 参数并接受输入两个返回的需要。
这是我能做到的最好的。任何人都可以改善这一点吗?或者有没有更好的方法来处理这个?我不敢相信没有。
最好采用某种方式安全地处理此问题,而无需输入密码,但这可能要求太多。每次脚本调用我都会满足于一次。
这是整个脚本的骨架形式的简化版本
#! /bin/sh
KEYFILE=$HOME/.ssh/id_dsa
PASSPHRASE=''
unset_passphrase() {
# params
# oldpassword keyfile
echo "unset_key_password()"
cmd="ssh-keygen -p -P $1 -N '' -f $2"
echo "$cmd"
$cmd
echo
}
reset_passphrase() {
# params
# oldpassword keyfile
echo "reset_key_password()"
cmd="ssh-keygen -p -N '$1' -f $2"
echo "$cmd"
$cmd
echo
}
echo "Enter passphrase:"
read -s PASSPHRASE
unset_passphrase $PASSPHRASE $KEYFILE
# do something with ssh
reset_passphrase $PASSPHRASE $KEYFILE
【问题讨论】:
标签: bash ssh passphrase