Setup SSH Keys for Secure Logins

Topics: Web Servers

SSH keys are an easier, more secure way of logging into your virtual private server via SSH. Passwords are vulnerable to brute force attacks and just plain guessing. Key-based authentication is (currently) much more difficult to brute force and, when combined with a password on the key, provides a secure way of accessing your VPS instances from anywhere.

Key-based authentication uses two keys, the first is the “public” key that anyone is allowed to see. The second is the “private” key that only you ever see. So to log in to a VPS using keys we need to create a pair — a private key and a public key that matches it — and then securely upload the public key to our VPS instance. We’ll further protect our private key by adding a password to it.

Open up your terminal application. On OS X, that’s Terminal, which is in Applications >> Utilities folder. If you’re using Linux I’ll assume you know where the terminal app is and Windows fans can follow along after installing Cygwin.

Here’s how to generate SSH keys in three simple steps.

Setup SSH for More Secure Logins

Step 1: Check for SSH Keys

Cut and paste this line into your terminal to check and see if you already have any SSH keys:

ls -al ~/.ssh

If you see output like this, then skip to Step 3:

id_dsa.pub
id_ecdsa.pub
id_ed25519.pub
id_rsa.pub

Step 2: Generate an SSH Key

Here’s the command to create a new SSH key. Just cut and paste, but be sure to put in your own email address in quotes:

ssh-keygen -t rsa -C "your_email@example.com"

This will start a series of questions, just hit enter to accept the default choice for all of them, including the last one which asks where to save the file.

Then it will ask for a passphrase, pick a good long one. And don’t worry you won’t need to enter this every time, there’s something called ssh-agent that will ask for your passphrase and then store it for you for the duration of your session (i.e. until you restart your computer).

Enter passphrase (empty for no passphrase): [Type a passphrase]
Enter same passphrase again: [Type passphrase again]

Once you’ve put in the passphrase, SSH will spit out a “fingerprint” that looks a bit like this:

# Your identification has been saved in /Users/you/.ssh/id_rsa.
# Your public key has been saved in /Users/you/.ssh/id_rsa.pub.
# The key fingerprint is:
# d3:50:dc:0f:f4:65:29:93:dd:53:c2:d6:85:51:e5:a2 scott@longhandpixels.net

Step 3 Copy Your Public Key to your VPS

If you have ssh-copy-id installed on your system you can use this line to transfer your keys:

ssh-copy-id user@123.45.56.78

If that doesn’t work, you can paste in the keys using SSH:

cat ~/.ssh/id_rsa.pub | ssh user@12.34.56.78 "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"

Whichever you use you should get a message like this:

The authenticity of host '12.34.56.78 (12.34.56.78)' can’t be established.
RSA key fingerprint is 01:3b:ca:85:d6:35:4d:5f:f0:a2:cd:c0:c4:48:86:12.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '12.34.56.78' (RSA) to the list of known hosts.
username@12.34.56.78's password: 

Now try logging into the machine, with ssh username@12.34.56.78, and check in:

~/.ssh/authorized_keys

to make sure we haven’t added extra keys that you weren’t expecting.

Now log in to your VPS with ssh like so:

ssh username@12.34.56.78

And you won’t be prompted for a password by the server. You will, however, be prompted for the passphrase you used to encrypt your SSH key. You’ll need to enter that passphrase to unlock your SSH key, but ssh-agent should store that for you so you only need to re-enter it when you logout or restart your computer.

And there you have it, secure, key-based log-ins for your VPS.

Bonus: SSH config

If you’d rather not type ssh myuser@12.34.56.78 all the time you can add that host to your SSH config file and refer to it by hostname.

The SSH config file lives in ~/.ssh/config. This command will either open that file if it exists or create it if it doesn’t:

nano ~/.ssh/config

Now we need to create a host entry. Here’s what mine looks like:

Host myname  
  Hostname 12.34.56.78
  user myvpsusername
  #Port 24857 #if you set a non-standard port uncomment this line
  CheckHostIP yes
  TCPKeepAlive yes

Then to login all I need to do is type ssh myname. This is even more helpful when using scp since you can skip the whole username@server and just type: scp myname:/home/myuser/somefile.txt . to copy a file.