即使它是从终端运行的,我也可以让SSH使用askpass程序吗?


9

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程序。

但是,如果弹出一个AskPass窗口,我会立即意识到。对我来说,这是一个足够好的折衷方案,只要我能使它起作用。


好问题。从源代码来看,它看起来并不像它。您必须欺骗它以致无法打开/dev/ttyLD_PRELOAD?)。
Celada's

@Celada启动外壳时会引起问题吗?
muru

可能不是...
Celada

Answers:


7

这会稍微复杂一点,但是将几部分组合起来将使其起作用:

说明

  1. 要强制ssh使用$SSH_ASKPASS程序,您不能允许ssh看到真实的tty。这只是条件。这可以通过使用setsid和使用-n切换到来完成ssh

    这种情况将启动连接,但是您将无法与外壳进行交互,这可能也是您的要求;)(并且还会破坏您的本地TTY)。

    但是您可以放弃“第一届会议”。您还应该添加-Nswitch,它将禁止远程命令并且仅执行身份验证

    &> /dev/null如果您不感兴趣,也可以将可能的输出“垃圾”重定向到。

  2. 设立ControlMasterssh_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

整个过程可以通过aliasbash函数或一步一步完成来简化,但这留给读者想象。

仅命令行参数

您可以在命令行中将这两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连接。

ControlMaster已经设置好,正是因为在这种情况下输入密码非常麻烦。编写一个测试现有母版并在未找到时使用AskPass的函数应该不难。谢谢!
muru

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

不幸的是,这对我不起作用。它确实说了Pseudo-terminal will not be allocated because stdin is not a terminal,所以似乎管道正在做某事。ssh </dev/null具有相同的效果。但是,在两种情况下,它仍然会要求输入密码,而且我仍然可以输入一个密码。我在Linux和Mac上尝试过。我试过了,ssh -vvv但是没有说什么有用的。
Timmmm

1
SSH_ASKPASS=/foo DISPLAY= setsid ssh host虽然有效。
Timmmm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.