How to use SSH keys for Authentication (for beginners)

SSH keys make my life easier on a daily basis. I use them to log into remote root and virtual private servers for various work and spare time projects, which is probably the most common use case.

The point of an SSH key is to authenticate you with another host, also for example with a git server in order to prove that you're really you.

In this example I'll create a Digital Ocean Droplet to create a Linux Server for the examples. Click the link for a 10$ credit with them ;) Another host I can recommend is Linode!

Generating an SSH key

Let's start by opening your favourite terminal, I recommend any Linux Terminal or iTerm2 on Mac OS, but most things will do.

ssh-keygen -t rsa -b 4096 -C "your_key_name"
Generating public/private rsa key pair.

Make sure to save the generated key either by the recommended name or at least inside your ~/.ssh directory. ~ expands to /home/your_username on Linux and /Users/your_username on Mac OS. You're free to rename the key files afterwards, they're only plain text files.

Enter file in which to save the key (/home/jonathan/.ssh/id_rsa):
/home/jonathan/.ssh/serenity

You'll be prompted to set a passphrase and as with all *nix like password fields on the terminal, you will not actually see the character count, but it's still capturing your input. You could leave this empty, but I don't recommend it.

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

Now it should yield the following output:

Your identification has been saved in /home/jonathan/.ssh/serenity.
Your public key has been saved in /home/jonathan/.ssh/serenity.pub.
The key fingerprint is:
32:fc:3b:3f:f2:2f:a2:1d:67:a8:79:4d:78:81:d7:4f serenity
The key's randomart image is:
+--[ RSA 4096]----+
|                 |
|                 |
|         . .     |
|     .  . o . E  |
|      + So . o   |
|       +..o   .  |
|        ++o      |
|       +==+      |
|      +oo*o+.    |
+-----------------+

Lastly we should make sure we're running the ssh-agent that picks up the keys when trying to login to a server.

eval "$(ssh-agent -s)"

Most likely that will return something like Agent pid 8711, the process id will vary. Now we have created two files:

  • serenity <- the private key, don't share this with anyone
  • serenity.pub <- the public key, give this to the server

Using SSH key based login

By default, Digital Ocean will ask you to assign one of your already added SSH keys to your newly created servers. This is very practical, but if you want to add another user, you'll need to add the keys manually to only that server, which is what we will do in this section.

digital-ocean-ubuntu-vps

Setting up the Server for SSH login

As mentioned I created a Digital Ocean Droplet, but any Linux server will do. I am logged in as the root user and I want to add another restricted user that's going to own the web project I'll work on. I'll call the project chameleon for now.

Note, the following commands are run on the server (serenity):

root@serenity:~# adduser chameleon
Adding user `chameleon' ...
Adding new group `chameleon' (1000) ...
Adding new user `chameleon' (1000) with group `chameleon' ...
Creating home directory `/home/chameleon' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for chameleon
Enter the new value, or press ENTER for the default
    Full Name []:
    Room Number []:
    Work Phone []:
    Home Phone []:
    Other []:
Is the information correct? [Y/n]

Now we have created a user with a password, but probably we set a safe, long and automatically generated one, right?! If you don't you're a security risk to your project. Now let's enable the ssh based login for the user chameleon. The username is identical to the project name in this case, but it doesn't have to be.

Note, the following commands are run on the server (serenity):

su chameleon
cd
ls -a

ls -a will show us all (also the hidden) files inside the user chameleons home directory. We see no .ssh directory, so we need to create it and the authorized_keys file.

Note, the following commands are run on the server (serenity) as the user chameleon:

chameleon@serenity:~$ mkdir .ssh
chameleon@serenity:~$ touch .ssh/authorized_keys

Now we open the file /home/chameleon/.ssh/authorized_keys with vim or nano.

Note: Instead of copy pasting, some awesome redditors have recommended using ssh-copy-id in order to transmit your public key! More info: man ssh-copy-id. I'm keeping my original method in order to display that things are very simple and that we're dealing with plain text files.

On your local machine, get the content of your generated key.pub and paste it into the authorized_keys file on the server.

# run on your local machine:
cat .ssh/serenity.pub                                                                  ~
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDE8wKtaZuDAv4GIPk0y7So9Q0blOpjaEwP74ZjBUJVUKUfJHoArOVm+U1TuqrC4mLb5/YjOAF+aupPTcgxkxEuCYxkkrRyQUTDF5kF6tGv6x2HLtgydX3Igz+LZDngQb/R7P9lVf6H2V3abwd9MIAGGSmpBnj9g4VipFxFr5QuZ94gfxWyhoflO4pyBY3hI+EfqxYAOTO4E8Gx+Le/rzXuuDUDIkomXAAq8bXqP4gdyjY9OJ7T3k23Z6h0yoxTkaGkAmKYQYqamm2qZ9xeyAfYvQ6eV0UgYcOejqj2DrznSWD693zE4ecF9FLyybPsdW6x/kzDQWCjEjuLhs3hZqGs6+5gLgHrFDor6GSMwrMVSeiqgHwLe5i0Tjisr9n2OpWJHYCByOgg+p1twB1FeMxINoeDvcKFLJqhswI+S7f3eHh9RQ8U21EinUd6dy4Q//A1Zw1gzcd+qOQTXCKObmOc6UmD2DKRELJxni3SczTbv+6M27j/xJ4kLLJcCzuoLjXfn/f2MizMamAsDozpArINV3lz7sscNr3ub6rgQ147mmVFcAVr+0UW08w8dPW7AZwN+lZoFLRVtFDvlvVxabbX08eCHv3EI8nSHxBxE/K6kJJz9NcH3aFm7eEya1tZBf0C1HnyMcB5lAdaANEHr+nuHFCQC99S2zomayLbDzs9vw== serenity

or open the your_key_name.pub file with your text editor.

To save the file on the server hit:

  • in nano: CTRL+O, ENTER and CTRL+O
  • in vim: :wq

Now you can login using your ssh key, let's switch back to our local machine and see if we can make it work.

Client side: edit your .ssh/config

In order to tell your local ssh that you want to use a specific key to log into a specific server, we'll add a block of text to the file ~/.ssh/config.

Host serenity
  HostName 138.68.88.146
  User chameleon
  IdentityFile ~/.ssh/serenity

The Host is the alias name you want to user for your server (mine is serenity). The HostName is the IP of your server. The User is your remote/server user. The IdentityFile is the path to your key file name of your ssh key.

Now try on your local machine:

Note: You only have to enter your ssh key passphrase once per login or you can add them to your keychain, so you won't have to type your password every time you want to log in (or use git with ssh).

ssh serenity
Enter passphrase for key '/home/jonathan/.ssh/serenity':
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-38-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

chameleon@serenity:~$

That's it! You've successfully logged in to your remote server using an SSH key file. Try opening up a terminal writing ssh serenity (or your server name) and you'll not be asked for a password.

Thank you so much for reading this post and let me know what you use SSH and SSH keys for!

Tagged with: #Linux #ssh #ssh keys #ssh_config

Thank you for reading! If you have any comments, additions or questions, please tweet or toot them at me!