Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an ssh key passphrase via environment variable

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.

like image 545
Sergei Voitovich Avatar asked Jul 13 '16 14:07

Sergei Voitovich


2 Answers

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 -
like image 148
Kevin Joyce Avatar answered Nov 10 '22 19:11

Kevin Joyce


So there are actually a few things that is important for what you are trying to do:

  1. DISPLAY must be set
  2. it must not have a terminal associated with it
  3. on some machines it may be necessary to redirect the input from /dev/null (mine is one of them).
  4. SSH_ASKPASS must contain an executable which outputs the passphrase on 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*
like image 27
Iwan Aucamp Avatar answered Nov 10 '22 17:11

Iwan Aucamp