I run shell script with ssh
command inside my application. Used private key is encrypted by passphrase and the problem is - I cannot interactively pass it when asked.Key is not added in ssh-agent
. I cannot execute ssh-add my_key
because the passphrase is suppose to be passed interactively. It's good for terminal communication, but not so good to use inside application.
The man page
says:
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 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.)
When I execute SSH_ASKPASS=file_with_passphrase ssh-add my_key
I still asked to type a passphrase, looks like env var is just ignored in that case. I tryed to execute ssh -o BatchMode=yes
and server just rejected encoded key because no one was able to decoded it.
I definitely can decode ssh key manually before using it in ssh-agent
but it looks like I'm about to get what I need from SSH_ASKPASS
variable, but I don't know how to make it work. Happy to get community help.
Edit: I am adding more details to this answer. If you have a PEM encoded private key with a password you can use openssl to decrypt the key first, as openssl will accept a passphrase on stdin.
To generate a new key that will work with this use this command:
ssh-keygen -t rsa -m pem -b 4096
It cannot be an 'OPENSSH' key. The start of an existing key that looks like this should work.
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,8032BCA01FB25FCCD89AFDED8DB52079
Then, you can use openssl to decrypt the key before sending it to ssh-add. Openssl accepts the passphrase on stdin with the -passin stdin
option and will by default output to stdout, then ssh-add can accept the unencrypted key on stdin by adding a -
as the first argument.
echo "$MY_PASSPHRASE" | openssl rsa -in my_encrypted_key -passin stdin | ssh-add -
So there are actually a few things that is important for what you are trying to do:
stdout
.So for an example of getting it to work (for me, should work on other linux also I guess):
Create dummy key:
ssh-keygen -t rsa -C se-so-38354773 -f /tmp/se-so-38354773.key -N 'se-so-38354773-pp'
Create askpass script to echo password files:
cat > /tmp/se-so-38354773-askpass <<EOF
#!/usr/bin/env bash
echo "${0}:${@} : this is for debugging to see if the echo script runs" 1>&2
echo "se-so-38354773-pp"
EOF
chmod +x /tmp/se-so-38354773-askpass
I placed this file in /tmp/ - but this is not a good for security unless you also change permissions on the file before writing to it to ensure that nobody else can read it (or set umask).
Then you can do ssh-add as follow:
DISPLAY=":0.0" SSH_ASKPASS="/tmp/se-so-38354773-askpass" setsid ssh-add /tmp/se-so-38354773.key </dev/null
The setsid
dissociates it from your terminal if there is one - This is not needed on my computer though - but yeah - I think it may be needed in some other contexts.
And when you are done testing do clean up:
ssh-add -d /tmp/se-so-38354773.key
rm /tmp/se-so-38354773*
Example output on my computer:
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ ssh-keygen -t rsa -C se-so-38354773 -f /tmp/se-so-38354773.key -N 'se-so-38354773-pp'
Generating public/private rsa key pair.
Your identification has been saved in /tmp/se-so-38354773.key.
Your public key has been saved in /tmp/se-so-38354773.key.pub.
The key fingerprint is:
SHA256:s+jVUPEyb2DzRM5y+Hm3XDzVRREKn5yU2d0hk61hIQ0 se-so-38354773
The key's randomart image is:
+---[RSA 2048]----+
| .E+=B=O|
| B*B*o=|
| X B*o o|
| o % o ..|
| S * ..+|
| . = . ...+|
| . o . o |
| . . |
| . |
+----[SHA256]-----+
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ cat > /tmp/se-so-38354773-askpass <<EOF
> #!/usr/bin/env bash
> echo "${0}:${@} : this is for debugging to see if the echo script runs" 1>&2
> echo "se-so-38354773-pp"
> EOF
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ chmod +x /tmp/se-so-38354773-askpass
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ DISPLAY=":0.0" SSH_ASKPASS="/tmp/se-so-38354773-askpass" setsid ssh-add /tmp/se-so-38354773.key </dev/null
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$
bash: : this is for debugging to see if the echo script runs
Identity added: /tmp/se-so-38354773.key (/tmp/se-so-38354773.key)
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ ssh-add -d /tmp/se-so-38354773.key
Identity removed: /tmp/se-so-38354773.key (se-so-38354773)
[email protected]:~/projects/gitlab.com/aucampia/stackexchange/stackoverflow/38354773
$ rm /tmp/se-so-38354773*
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With