man ssh
说:
SSH_ASKPASS
If ssh needs a passphrase, it will read the passphrase from the
current terminal if it was run from a terminal. If ssh does not
have a terminal associated with it but DISPLAY and SSH_ASKPASS
are set, it will execute the program specified by SSH_ASKPASS
and open an X11 window to read the passphrase.
我希望 SSH 使用askpass 程序,即使它是从终端运行的。
有时,我必须连接到服务器,在显示密码提示时会出现一些延迟(可能是由于网络问题,可能是由于尝试反向 DNS 查找,...)。我很恼火,转而做其他事情,然后忘记了尝试的连接。 (插入有关金鱼注意力持续时间的笑话。)当我最终回到它时,提示已超时,即使正确的密码也只会导致连接关闭。
密钥是一种解决方案,但并非我使用的每个系统都有常用的 SSH 密钥。不过,我通常使用Ubuntu系统,Ubuntu默认安装了一个SSH Askpass程序。
然而,如果弹出一个询问窗口,我会立即意识到这一点。这对我来说是一个足够好的妥协,只要我能让它发挥作用就好了。
答案1
使用 OpenSSH 8.4,您可以将$SSH_ASKPASS_REQUIRE
环境变量设置为force
.引用SSH(1)手册页:
SSH_ASKPASS_REQUIRE Allows further control over the use of
an askpass program. If this variable
is set to "never" then ssh will never
attempt to use one. If it is set to
"prefer", then ssh will prefer to use
the askpass program instead of the TTY
when requesting passwords. Finally, if
the variable is set to "force", then
the askpass program will be used for
all passphrase input regardless of
whether DISPLAY is set.
随着 OpenSSH 8.4 的发布2020 年 9 月 27 日您需要等待一段时间才能在任何主要 Linux 发行版中使用此功能。
答案2
这会有点复杂,但是几个部分的组合将使它起作用:
解释
为了强制
ssh
使用$SSH_ASKPASS
程序,你不能允许ssh
看到真实的tty
。这只是条件。这可以通过setsid
使用-n
switch to来完成ssh
。这种情况会启动连接,但您将无法与 shell 交互,这可能也是您的要求;)(并且还会破坏您的本地 TTY)。
但你可以放弃“第一届会议”。您还应该添加
-N
开关,它将抑制远程命令并执行只是认证。&> /dev/null
如果您对此不感兴趣,也可以将可能的输出“垃圾”重定向到它。设置
ControlMaster
于ssh_config
.这是一个很酷的功能,一旦建立连接,您就可以非常快速地“启动”会话。这段代码~/.ssh/config
应该做到这一点:ControlPath ~/.ssh/controlmasters/%r@%h:%p ControlMaster auto ControlPersist 5m
您可以将其添加到
host
列出您的“慢候选人”的某个块中,或者只是添加到任何地方。几乎没有任何开销。
最后一行
然后您应该能够以这种方式连接到您预计需要一段时间的主机:
setsid ssh -nN host
# wait, insert password in the X11 prompt
ssh host
# will bring you directly to your session
整个过程可能会通过alias
bash 函数一步完成这两个过程来简化,但这取决于读者的想象。
仅命令行参数
您可以在命令行上将两者结合在一起,而不需要ssh_config
任何部分:
setsid ssh -nNMS ~/.ssh/masters/%C host
# wait, insert password in the X11 prompt
ssh -S ~/.ssh/masters/%C host
# will bring you directly to your session
当未指定 SSH 选项时,以下函数应该起作用:
ssh() {
if ! command ssh -o PasswordAuthentication=no "$1" true
then
setsid -w ssh -fnN "$1"
fi
command ssh "$@"
}
-f
指示 SSH 在程序执行之前(即获取密码之后)进入后台。-w
告诉setsid
等待程序结束。在这种情况下,当 SSH 进入后台时就会发生这种情况。与 结合使用ssh -f
,可以消除两个 SSH 命令之间的手动等待。- 该函数假设第一个参数是主机名。
- 该测试只是为了防止不必要的 SSH 连接。
答案3
每个 SSH 手册 ( man ssh
):
如果
ssh
没有与其关联的终端,但设置了 DISPLAY 和 SSH_ASKPASS,它将执行 SSH_ASKPASS 指定的程序。
因此,您需要取消与终端的关联(例如通过添加管道)并确保DISPLAY
未设置(如果您想使用终端作为密码短语)。
简单的例子:
echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh ...
与以下相同ssh-add
:
$ echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh-add id_rsa
ssh_askpass: exec(/my/cmd): No such file or directory