ssh-everywhereAWS has made virtual machines (EC2) ubiquitous. You can launch and stop them as will, log into them, create new accounts, etc. Then you start digging into remote control for multiple users. How do I set up a ssh connection between my local client and a remote machine? Which key should I use? How do I setup a passwordless ssh? These are the practical questions answered in this post.

ssh, which stands for Secure Shell, is a network protocol that establishes an encrypted communication between two hosts. It is used to securely launch a command on a remote host, to log into that host, or to securely move files between the two hosts (via the command scp). It uses public and private keys to establish a handshake between the two hosts, so that they can agree on a fast cipher for the rest of the communication.

Assume you are user johnsmith on localhost, and you want to set up a passwordless ssh as johnny on remotehost. First thing you need is to generate your public and private keys. This is done with ssh-keygen:

johnsmith@localhost:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/johnsmith/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
a1:81:5a:05:d0:be:fe:cd:27:37:aa:58:57:24:c1:70 johnsmith@localhost
The key's randomart image is:
+--[ RSA 2048]----+
|  .o..ooE        |
|    .o ...       |
|   .o . o .      |
|   o.  o +       |
|  .  .. S .      |
|    .    .       |
|   .  . .        |
|    .o +. +      |
|    ..o.+= .     |
+-----------------+

You will be prompted for a key name and a passphrase. Leave the passphrase empty. By default the public and private keys are stored in directory ~/.ssh as id_rsa.pub and id_rsa respectively. You can choose to name the keys as you please. This is useful when you want to access different remote systems with different keys –more on this later.

The type of the key, indicated with the option –t, is either rsa or dsa. It describes the cryptographic algorithm used for the handshake. It is still debated whether RSA or DSA is better. I would recommend RSA though because:

  1. ssh-keygen forces the DSA key to be exactly 1024 bits. On the other hand, the RSA key bit length can be set using the –b option, up to 2^15 = 32768 bits. The RSA key is 2048 bits by default, which is considered safe.
  2. DSA is pushed by government agencies…

Whenever you ssh the remote host as johnny, you need to enter johnny’s password. That is not practical when writing scripts that invoke commands on remote machines. Also a password can be guessed or stolen –using brute-force approaches, or with social engineering techniques (phishing, impersonation, etc).

Much more practical and safer is to have a passworless ssh. We are going to allow public key-based authentication on the remote host. This means that a guest with a private key that matches a public key authorized by the remote host will be granted access without a password.

First, we need to add your public key to the remote host’s set of authorized key. Simply login to the remote host, edit its ~/.ssh/authorized_keys file, and cut-and-paste your public key (in our example, id_rsa.pub) to the file. We can also use scp to transfer the file. scp stands for Secure Copy, and is built on top of ssh:

# Copy the public key on the remote host as 'foo'
johnsmith@localhost:~$ scp ~/.ssh/id_rsa.pub johnny@remotehost:foo
johnny@remotehost's password: 
id_rsa.pub                                  100%  425     0.4KB/s   00:00
# Log into remote host
johnsmith@localhost:~$ ssh johnny@remotehost
johnny@remotehost's password: 
johnny@remotehost> 
# Add the public key to the authorized keys
johnny@remotehost> cat foo >> ~/.ssh/authorized_keys ; rm foo

Make sure that the file permission is proper: the .shh files may not be written or read but by the user.

johnny@remotehost> chmod 700 ~/.ssh
johnny@remotehost> chmod 600 ~/.ssh/authorized_keys
johnny@remotehost> ls –al ~/.ssh
total 12
drwx------  2 johnny johnny 4096 Oct 25 01:39 ./
drwx--x--- 19 johnny nobody 4096 Oct 26 04:31 ../
-rw-------  1 johnny johnny 425 Oct 25 01:39 authorized_keys

Finally, make sure that the remote host’s ssh is configured for public key-based recognition. Look for the following lines in the /etc/sshd/sshd_config file, which configures the ssh server:

PubkeyAuthentication yes
RSAAuthentication yes
PasswordAuthentication no

The first two lines authorize authentication with an RSA public key. The third line specifies whether a username + password authentication is allowed. If set to no, only passwordless ssh is allowed on the remote host: password cracking on the host becomes irrelevant. You can access the remote host only if you have the correct private key.

Note that if you need to modify the /etc/sshd/sshd_config configuration file, you will have to restart the ssh server:

johnny@remotehost> /etc/init.d/ssh restart

That’s it. The remote host will grant (passwordless) access to guests with the appropriate private key only –no more password. Your local client is the only system to store your private key, thus only you can access the remote host.

If you want to manage several remote systems independently, you can create a key pair for each system, for instance naming the keys host1_id.pub and host1_id for host host1. You can then ssh a specific host using the –i option to authenticate yourself with the appropriate private key, e.g.:

johnsmith@localhost:~$ ssh –i ~/.ssh/host2_id johnny@host2.com 'echo "I am `who am i` on `hostname`"'
I am johnny on host2
johnsmith@localhost:~$ 

Have fun with your array of remote hosts, and be safe!

Tags:

Leave a Reply