So you have your own Linux/Unix server. Congratulations! You probably access it using SSH protocol. Most people start using SSH by using password-based login, but re-entering the password every time when connecting to the server can become very tedious, especially when doing repetitive tasks.
OpenSSH has many powerful features that render system management easier if you take the time to learn about them. In this post I’m going to describe how to setup key-pair authentication for OpenSSH.
Public key-based authentication is the most secure authentication method usable with SSH. It has several advantages over password-based authentication, the most important being the fact that the key values are significantly more difficult to brute-force than simple passwords.
How it works
The principle behind key-based authentication is fairly simple. Say that we want to set it up for a user called “bob”. On the client side, we create an asymmetric key pair (a public key and a private key). We keep both keys on the client side and we copy the public key to “/home/bob/.ssh/authorized_keys” on the remote server that we wish to access.
This way, when we connect to the remote server, we send our key ID to it. Using the ID, the server then looks for our public key, generates a random number and encrypts it using the public key, and sends that value back to us. Since we have the private key on our side, we are able to decrypt the message from the server and retrieve the number. We then compute a hash value based on this number and a pre-negotiated session ID and then we send this hash to the server. The server performs the same hash operation on its copies of those values and compares it with the hash received from us. If the hashes are equal, we will be able to log into that server.
The first thing that we need to do is to generate the public and private key pair on our local workstation:
$ ssh-keygen -t rsa -b 2048 Generating public/private rsa key pair. Enter file in which to save the key (/home/andrei/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/andrei/.ssh/id_rsa. Your public key has been saved in /home/andrei/.ssh/id_rsa.pub. The key fingerprint is: SHA256:4LA4fviggojyZBxbxmLoPdCtR8HwCzS+TExRnh3Br34 firstname.lastname@example.org The key's randomart image is: +---[RSA 2048]----+ | *o..o. | | = * o.. | | =.*... | | .+o++o. . | |..*+=+. S | |.+oOo . | |+.O+... | |*+ +o . E | |+.. . . | +----[SHA256]-----+
What just happened? We generated a 2048-bit keypair using the RSA algorithm (I encourage using at least 2048 bits size, since 1024-bit key pairs can be broken nowadays). The passphrase is used to encrypt the private key and is optional (if we don’t want to enter a passphrase, just hit Enter). This way, if the private key is compromised and falls into the wrong hands, the passphrase is required to decrypt it in order to use it.
So now that we have generated the private and public keypair, we can find these two in the .ssh directory of our user’s root directory. Let’s take a peek:
$ ls -al ~/.ssh drwx------ 10 andrei staff 340 Aug 5 17:10 . drwxr-xr-x+ 49 andrei staff 1666 Aug 5 13:33 .. -rw------- 1 andrei staff 1766 Aug 5 17:10 id_rsa -rw-r--r-- 1 andrei staff 409 Aug 5 17:10 id_rsa.pub
As you might have guessed, the id_rsa file contains our private key and needs to be kept extremely secure. The id_rsa.pub file contains our public key, and this is the key that we want to distribute to the server we want to log into.
OpenSSH provides a utility called ssh-copy-id that allows us to move this key from one server to another. Basically, what it’s going to do is use secure shell to copy the file under the hood from our local workstation to the remote server:
$ ssh-copy-id -i id_rsa.pub email@example.com The authenticity of host 'hincu.io (192.168.1.200)' can't be established. RSA key fingerprint is 6a:de:e0:af:56:f8:0c:04:11:5b:ef:4d:49:ad:09:23 Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys firstname.lastname@example.org's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'email@example.com'" and check to make sure that only the key(s) you wanted were added.
The purpose of this fingerprint is to check that if something changes on the server that causes that key to be regenerated, that would display a different fingerprint, so we would know there’s something wrong with the server we are trying to connect to. So we choose “yes” and hit Enter, and now the SSH password of bob’s user account needs to be typed, so we can log in using SSH and add the public key to the list of trusted keys. We get the confirmation from the message “Number of key(s) added: 1”, so now let’s try to login to the server:
$ ssh firstname.lastname@example.org [email@example.com ~]$
We’re in! We were able to login into the server without providing the user account’s password. Let’s take a peek at the “authorized_keys” file on the server to see how it looks like:
[firstname.lastname@example.org ~]$ cat ~/.ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCoxybXzoJFTA3MlWBi0efui0PN3Hh20PrNZBKaJ6zg4xiO9kuuY0kNxld8EbXgvJvLpWzb296UyrnoOMHP5Po1E7Apwcnwo8t75tPCF6WMZh7fxajoZyvo3qPuJ4bgW+YnNJyB6SqVkPKa+uCfXjSSaFVFsNQj+yi1rpbM9LDFgKhhW+bopKp5LtIyfraBmqe5Mk6NAZxcpchkQtGtfNum3bE64XhxSHgkWYk9tr6S9tus5vkHa2kFDz0Zp38ZBXxgyEPBpldEniYAm4sR2UOFYfC77k0U6nfMIu0x5M35bNH3rzKMp7uuAALYlxZReLK56c8JhYNevMcPofFGpDO5iYdEmQxGSHkfORGzEXuS01KMKHvgnakfZq41H7PhIT8fr/YqrCNz27qSpu5BpGe+ssG6mH5vTWypZ4bzXqShRxWy9hrqkMziIJ3/FXJ2E5AEZOVz8o651awKR3DGaQ7HDeXOECpR9vREVAUEd7QhbutVFq58q3RG7JL7b/WOQJl6FDLGXLmcWd9zn+IJoyQG1UJATV2ljvLGXeeyd9T1E38u0/C31KOYM1m052HBQQyjoDDV/rGHN4YsiMnZZOXbR9S+mYEvFH9iWdUfbf7Iba1hO2pS4pgUisShSfqHIit28g78yA/0TxJm7HuAj1TsiblTqugpX6vHYZS+cWpd/w==
In this post I showed you how to use OpenSSH to keep an SSH connection to a remote server secure using public key cryptography. I also showed you how OpenSSH handles authentication. While we haven’t even scratched the surface of OpenSSH, because it’s full of options for automating and securing communications, we now know how to log in remotely without having to type our password.