(我已经阅读了本网站上许多看起来相关的问题,我相信这是一个真正的新问题。)
我在很多服务器上都有很多密钥,它们都受到密码保护。
我喜欢输入密码,就像我喜欢输入密码一样 - 这是一个真正的生产力消耗。
ssh-agent + ssh-add命令可用于登录 shell,这意味着您只需在登录时输入一次密码
钥匙串可用于在注销后保持 ssh 代理处于活动状态,例如,您可以拥有它,因此您只需在启动时输入一次密码,或者您可以让它保持活动状态一小时左右。
我遇到的问题是,这两种解决方案通常都是在 shell 登录(例如.zshrc
)中启动的,依赖于我在登录时输入我的密码,即使我不需要解锁它。(我对钥匙串让代理无限期地活着不满意。)
我想要的是仅在需要时提示输入密码(对于代理)。
这样我就可以登录到服务器A,做一些东西,然后ssh到服务器B,并在该点被要求提供密码。在服务器 B 上做一些事情,注销。回到 A,做一些更多的事情,再次 ssh 到 B 并且不需要我的密码(它由代理持有)。
我注意到这在像 Gnome 这样的图形桌面上是可能的——当你尝试 ssh 时,你会得到一个弹出窗口,要求输入密码来解锁你的私钥。所以这就是我所追求的,但来自控制台。
小智 22
不要在任何 shell 启动脚本中添加任何内容,这是不必要的黑客行为。
相反,添加
AddKeysToAgent yes
Run Code Online (Sandbox Code Playgroud)
到您的 .ssh/config
像这样,ssh-add 会在您第一次通过 ssh 进入另一个盒子时自动运行。您只需在 ssh-agent 过期或重新启动后重新输入您的密钥。
Zsh有一个preexec
钩子,它在执行命令行上输入的命令之前执行一个函数。这是一个ssh
在命令行中查找的钩子,如果找到,则检查 ssh 代理是否存在。如果没有找到,它会运行钥匙串。
这样一来,钥匙串仅在 ssh 命令之前运行,然后仅在需要时运行。
把它放在你的~/.zshrc
:
function check_ssh {
[[ $3 =~ '\bssh\b' ]] || return
[[ -n "$SSH_AGENT_PID" && -e "/proc/$SSH_AGENT_PID" ]] \
&& ssh-add -l >/dev/null && return
eval `keychain --eval id_dsa --timeout 60`
}
autoload -U add-zsh-hook
add-zsh-hook preexec check_ssh
Run Code Online (Sandbox Code Playgroud)
这里发生的情况是,无论何时键入命令,check_ssh
都会在执行命令之前调用。
该函数的第一行检查扩展命令是否ssh
使用 Zsh 正则表达式。两边ssh
必须有字边界\b
。如果未找到,则该函数返回。
下一行检查环境变量中是否存在 SSH 代理进程,并且该进程仍然存在于进程表中,然后至少一个密钥已添加到代理中。如果一切正常,那么 ssh 代理就设置好了,我们不需要做任何事情,所以它会返回。
最后,我们启动钥匙串,让代理保持活动一个小时。
它仍然存在有关嵌入式 ssh 内容的问题,例如git
orrsync
或scp
as 不会触发该功能(您可以将这些添加到正则表达式中)。
归档时间: |
|
查看次数: |
6910 次 |
最近记录: |