SSH (Secure Shell) allows simple establishment of an encrypted and authenticated connection between computers. In this article I will focus on establishing SSH tunnels without using a password by using asynchronous key pair. This approach is especially very useful in machine-to-machine communication.

The idea grounds on asymmetric cryptography, that describes a concept of a key -pair of a private and public keys. In this article it’s sufficient to know, that:

  • you should never share your private key (usually the PK don’t leaves the machine it was created on)
  • you need to share your public key with domains that should be able to identify you.

Let’s start by generating a needed key pair.

Generating Keys

Even if key authentication in SSH has many advantages over the authentication with passwords, by default requires you to type something in: this time it’s the passphrase of your private key.

There are several different approaches how to deal with that..

Empty passphrase (convenient)

I don't recommend you do use this way. Because it means you're private key is theoretically less protected.

This method is very convenient because it allows using the key “as is” in the headless scenario. Just execute the following and do not enter any passphrase (just hit enter on the question).

$ ssh-keygen -t rsa

RSA1 key-pair as following files in ~/.ssh directory:

  • id_rsa
  • id_rsa.pub

Now public key needs to be copied to the remote host and has to be added to end of ~/.ssh/authorized_keys file.

Passphrase + ssh-agent

Providing a passphrase increases security. But you will be prompted for a passphrase every time. Here ssh-agent comes to play, it a small daemon running in the background caches our passphrases in the memory, and then they are automatically used when we make the connection to the SSH server.

There are several ways to start the agent. Here is the example

# start the ssh-agent in the background
$ eval "$(ssh-agent -s)"
> Agent pid 39231
$ ssh-add
> Enter passphrase for /home/currentuser/.ssh/id_rsa: 
# type passprhase for ea key.
> Identity added: /home/currentuser/.ssh/id_rsa (/home/you/.ssh/id_rsa)

Having

eval `ssh-agent`

in your systems ~/.bash_profile will start agent every time on login of the user. In that scenario you only need to enter the passphrase once after start of the ssh-agent.

However this is still not working for completely headless scenarios and here ssh-add command comes to play. Unfortunately the use of

echo "passphrase\n" | ssh-add

will now work as probably anticipated on the first sight in the absence of user. This because ssh-add does not read the passphrase from stdin, but opens /dev/tty directly for reading. This can be worked around with a tool for automating interactive applications.

Transfer Public keys

The best way to do it is to use ssh-copy-id program which is inside of many Linux distributions.

ssh-copy-id -i ~/.ssh/id_rsa.pub remote-user@remote-server.org

In that case everything is done automatically and you are ready after that. But if ssh-copy-id is not available, you can copy keys manually e.g. like that.

cat ~/.ssh/*.pub | ssh remote-user@remote-server.org 'umask 077; cat >> .ssh/authorized_keys'

Test

Now remote login, scp and sftp can be used without password. Test it:

# establish connection
$ ssh remote-user@remote-server.org
#or copy files secure and password-less.
$ scp /home/user/some-file remote-user@remote-server.org:/some-path/dir/

Have fun. Ask questions. P.S. On some linux distributions SSH2 searches for keys in ~/.ssh/authorized_keys2. Not so in actual Debian (Lenny), but seems to be so in SuSe linux.


  1. RSA is one of the first practical public-key cryptosystems and is widely used for secure data transmission ↩︎