Working with SSH keys

If you've used GitHub or a VPS, you've probabaly encountered SSH keys and a basic intro to using them. If you haven't yet, SSH keys are fantastic: they're more secure than passwords and you don't have to remember them whenever you want to access a service, the SSH protocol handles it for you.

SSHing into Mordor

But what happens when you have multiple SSH keys that you need to manage, for as many services? How do you keep track of all the keys and the accurate associated service?

Enter SSH config.

Setting up

If you're using a Mac like me, your computer already comes with SSH installed. You can double check this in the terminal

$ ssh
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]  
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]

NOTE: If you don't have SSH installed, you can use your package manager of choice to install it

Let's say you have a server at some host or ip. By default, the SSH port is 20, but it's good practice to change it to something else, as well as add a non-root user as your main entry point into the VPS. Here's a great article to get you started if all of this is new to you.

So you've added your first non-root remote user on the server, and you're hyped to get an SSH key set up so you don't have to keep doing this

$ ssh <REMOTE USER>@<HOST> -p <PORT>
Enter <REMOTE USER>'s password: ********  

No, that is awful, clunky and insecure to boot.

NOTE: All placeholders in the code snippets throughout this tutorial are denoted with uppercase strings encapsulated in chevrons. Please replace them with your own information.


ssh-keygen

In your Terminal, generate a new key pair and configure it properly.

$ ssh-keygen -t rsa

That will start off the process, and it will first ask you to pick a file name for your new key-pair. In case you're wondering, the -t rsa flag is telling the command to use the TSA protocol.

Pick a descriptive and terse filename here. Do not let it default to id_rsa, as it isn't descriptive and you may overwrite an older (and, following Murphy's Law, more important) SSH key by mistake.

Generating public/private rsa key pair.  
Enter file in which to save the key (/Users/<USER>/.ssh/id_rsa): /Users/<USER>/.ssh/<FILENAME>  

Next up is a passphrase. Think of this as 2-step authentication, where the server requires both the key-pair and a passphrase to allow access. This is obviously more robust than not having a passphrase, but it isn't always necessary. Press ENTER twice if you want to skip this part.

Enter passphrase (empty for no passphrase):  
Enter same passphrase again:  

Congratulations, you have your shiny new key-pair ready for use!

Your identification has been saved in <FILENAME>.  
Your public key has been saved in <FILENAME>.pub.  
The key fingerprint is:  
10:70:ae:8f:c2:4b:2f:bd:ea:a7:0b:df:f5:45:1d:c6 <USER>@<COMPUTER NAME>  
The key's randomart image is:  
+--[ RSA 2048]----+
|    ..o          |
|     o .   .     |
|      o     E    |
|     . .   o .   |
|    .   S . .    |
| .   o   .       |
|. +.. o   .      |
| +.=o. . .       |
| .B*+.  .        |
+-----------------+

ssh-copy-id

Before we can use the SSH key to get into the server, we have to copy over the public key, which was created along with the private key.

$ cd ~/.ssh
$ ls
<FILENAME>    <FILENAME>.pub  

Ok that's great, but how do we get this up to the server? The easiest way to do it is by using ssh-copy-id. If you're on a Mac, this doesn't come bundled by default, so you'll have to install it via Homebrew or another package manager.

$ brew install ssh-copy-id

NOTE: If you use something other than Homebrew, check here for installation details.

Once you have it installed, all you have to do is copy up the public key to the server, specifying which user on the server you want this SSH key to target.

$ ssh-copy-id -i ~/Users/<USER>/.ssh/<FILENAME>.pub -p <PORT> <REMOTE USER>@<HOST>

You'll be prompted to enter the remote user's password. Enter it with glee, knowing that it will be the last time you'll have to do it!*

It's time to test your newfound SSH powers out

$ ssh <REMOTE USER>@<HOST> -p <PORT> -i <FILENAME>

If all went smoothly, you should be in without needing to provide the dreaded password. If you set up a passphrase when generating the key-pair, the server will ask you for it now.

*Hopefully


~/.ssh/config

This part is optional, but I recommend it to anyone who doesn't want to type out that entire SSH command everytime they want to SSH into their server.

$ ssh <REMOTE USER>@<HOST> -p <PORT> -i <FILENAME>

That's worse than a password! What we want is some sort of alias that can store all of this information and allow us to simplify our SSH command.

$ ssh server

That is WAY nicer. Here's where the config file comes in. Let's get the config file set up, and take it for a spin.

$ cd ~/.ssh
$ touch config

Open up your config in your favourite editor (I'm using Sublime Text 3) and add in your first SSH alias.

$ subl config
Host server  
  HostName <HOST>
  User <REMOTE USER>
  Port <PORT>
  IdentityFile ~/.ssh/<FILENAME>

Save and close it. Now you are truly done. Running the following command will take you into your server. How cool is that?

$ ssh server

If you run into any errors here, you can debug by running SSH in verbose mode.

$ ssh server -v
comments powered by Disqus