rtacconi
rtacconi

Reputation: 14779

Specify private key in SSH as string

I can connect to a server via SSH using the -i option to specify the private key:

ssh -i ~/.ssh/id_dsa user@hostname

I am creating a script that takes the id_dsa text from the database but I am not sure how I can give that string to SSH. I would need something like:

ssh --option $STRING user@hostname

Where $STRING contains the value of id_dsa. I need to know the --option if there is one.

Upvotes: 50

Views: 74883

Answers (4)

Kruzchy Klaperman
Kruzchy Klaperman

Reputation: 107

I was looking at the same problem. Adding private key content to ssh command via stdin did not work for me. I found out that its possible to add the private key file contents to ssh-agent using the command ssh-add. This will let you ssh into the remote host without explicitly specifying the identity file. My particular usecase was that I didn't want to store the SSH key in cleartext on my machine and was dynamically getting it from a secrets vault. This answer is mostly a collection of other answers on StackOverflow.

ssh-agent is a program to hold private keys used for public key authentication. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh

Source

This is what I have done. First start the ssh-agent.
You can start it from your terminal by simply executing ssh-agent.
OPTIONAL: If you'd like to make sure ssh-agent is running on every login, you can add something like the following to your shell config. This is what I have added to my ~/.bashrc file.

# set SSH_AUTH_SOCK env var to a fixed value
export SSH_AUTH_SOCK=~/.ssh/ssh-agent.sock

# test whether $SSH_AUTH_SOCK is valid
ssh-add -l 2>/dev/null >/dev/null

# if not valid, then start ssh-agent using $SSH_AUTH_SOCK
[ $? -ge 2 ] && ssh-agent -a "$SSH_AUTH_SOCK" >/dev/null

Source (This particular snippet also makes sure new ssh-agent processes are not getting created when there's one already running.)

Now you have the ssh-agent running. Since we're interested in loading SSH key as a string, I'll assume a scenario where private key contents has already been loaded in to a variable, $SSH_PRIVATE_KEY.

I can now add this Key contents to the ssh-agent by executing the following command.

ssh-add - <<< "${SSH_PRIVATE_KEY}"

This can just be added to the bashrc file as well. You can confirm that your key has been added by listing all keys by executing ssh-agent -l. Aaand you're done now.

Try connecting to the remote host and you don't need a private key file.

ssh username@hostname

This does come with extra security risks. These are some I could think of:

  1. Adding the private key to the ssh-agent will let any process on the machine access the key to authenticate remote hosts without explicitly providing any information.
  2. Since the goal is to load Private key as a string, it will either be stored in a variable or the contents embedded directly in the command. This might make the key available in command history, the shell variable and other places.

Upvotes: 5

SAGAR BHOOSHAN
SAGAR BHOOSHAN

Reputation: 329

Passing cryptokey as a string is not advisable but for the sake of the question, I would say I came across the same situation where I need to pass key as a string in a script. I could use key stored in a file too but the nature of the script is to make it very flexible, containing everything in itself was a requirement. so I used to assign variable and pass it and echo it as follows :

#!/bin/bash
KEY="${ YOUR SSH KEY HERE INSIDE }"
echo "${KEY}" | ssh -q -i /dev/stdin username@IP 'hostnamectl'
exit 0

Notes: -q suppress all warnings

By the way , the catch here in above script, since we are using echo it will print the ssh key which is again not recommended , to hide that you can use grep to grep some anything which will not be printed for sure but still stdin will have the value from the echo. So the final cmd can be modified as follows :

#!/bin/bash
KEY="${ YOUR SSH KEY HERE INSIDE }"
echo "${KEY}" | grep -qw "less" | ssh -q -i /dev/stdin username@IP 'hostnamectl'
exit 0

This worked for me.

Upvotes: 2

user2132025
user2132025

Reputation: 529

Try the following:

echo $KEY | ssh -i /dev/stdin username@host command

The key doesn't appear from a PS statement, but because stdin is redirected it's only useful for single commands or tunnels.

Upvotes: 52

Kimvais
Kimvais

Reputation: 39578

There is no such switch - as it would leak sensitive information. If there were, anyone could get your private key by doing a simple ps command.

EDIT: (because of theg added details in comment)

You really should store the key in to a temporary file. Make sure you set the permissions correctly before writing to the file, if you do not use command like mktemp to create the temporary file.

Make sure you run the broker (or agent in case of OpenSSH) process and load the key using <whatever command you use to fetch it form the database> | ssh-add -

Upvotes: 17

Related Questions