How to pass a passphrase to ssh-add without triggering a prompt?
From the ssh-add
manpage:
DISPLAY and SSH_ASKPASS
If ssh-add needs a passphrase, it will read the passphrase from
the current terminal if it was run from a terminal. If ssh-add
does not have a terminal associated with it but DISPLAY and
SSH_ASKPASS are set, it will execute the program specified by
SSH_ASKPASS (by default ``ssh-askpass'') and open an X11 window
to read the passphrase. This is particularly useful when calling
ssh-add from a .xsession or related script. (Note that on some
machines it may be necessary to redirect the input from /dev/null
to make this work.)
So we can use this to cheat a little.
We start with no identities in the agent:
$ ssh-add -l
The agent has no identities.
So now we need a program that will supply the password:
$ cat x
#!/bin/sh
echo test123
And then convince ssh-add to use that script:
$ DISPLAY=1 SSH_ASKPASS="./x" ssh-add test < /dev/null
Identity added: test (sweh@godzilla)
And there it is:
$ ssh-add -l
2048 SHA256:07qZby7TafI10LWAMSvGFreY75L/js94pFuNcbhfSC0 sweh@godzilla (RSA)
Edit to add, based on revised question:
The password could be passed as a variable, and the askpass script use that variable.
For example:
$ cat /usr/local/sbin/auto-add-key
#!/bin/sh
echo $SSH_PASS
$ SSH_PASS=test123 DISPLAY=1 SSH_ASKPASS=/usr/local/sbin/auto-add-key ssh-add test < /dev/null
Identity added: test (sweh@godzilla)
In the workflow presented you would do SSH_PASS=$passphrase
to use the newly generated passphrase.
You can use script(1)
as a mini-expect
.
On Linux:
{ sleep .1; echo password; } | script -q /dev/null -c 'ssh-add /path/to/identity'
On BSD:
{ sleep .1; echo password; } | script -q /dev/null ssh-add /path/to/identity
You may want to increase the delay (sleep .3
or sleep 1
) if the right hand of the pipeline is slow to start. For anything more complex, use expect
. Do not use sshpass
since it's really no better than script
and itself subject to races.