Configure SSH Key Based Authentication On Ubuntu 20.04 Linux Server
SSH, or secure shell, is an encrypted protocol used to administer and communicate with servers. When working with a Linux server, chances are, you will spend most of your time in a terminal session connected to your server through SSH. There are a few distinct ways of logging into an SSH server, the two most popular are as follows:
- Passwords based authentication
- Public key based authentication
SSH keys provide an easy, yet extremely secure way of logging into your server. For this reason, this is the method we recommend for all users. We can use SSH keys for authentication when we are connecting to our server, or even between our servers. They can greatly simplify and increase the security of our login process. When keys are implemented correctly they provide a secure, fast, and easy way of accessing your cloud server.
How Do SSH Keys Work?
SSH key pairs are two cryptographically secure keys that can be used to authenticate a client to an SSH server. Each key pair consists of a public key and a private key.
The private key is retained by the client and should be kept absolutely secret. Any compromise of the private key will allow the attacker to log into servers that are configured with the associated public key without additional authentication. As an additional precaution, the key can be encrypted on disk with a passphrase.
The associated public key can be shared freely without any negative consequences. The public key can be used to encrypt messages that only the private key can decrypt. This property is employed as a way of authenticating using the key pair. Anytime we want to enable key-based authentication on a server, this public key should be stored on a remote server that we want to be able to log into with SSH. The key is added to a special file within the user account you will be logging into called ~/.ssh/authorized_keys
.
When a client attempts to authenticate using SSH keys, the server can test the client on whether they are in possession of the private key. If the client can prove that it owns the private key, a shell session is spawned or the requested command is executed.
Basically, here are the steps required to enable SSH key-based authentication on Linux server:
- Generate the ssh key pair.
- Install the public key in remote server.
- Test key-based authentication.
- Add ourselves to administrative group.
- Disable the password login.
- Final test and verification.
NOTE: In this article I'm using Ubuntu 20.04. If you're using another distribution, some command might have slight difference.
Generate SSH Key Pair
To generate SSH key pair (private and public key), we're using this command:
$ ssh-keygen -t rsa
We will be prompted to supply a filename (for saving the key pair) and a password (for protecting our private key):
- Filename: To accept the default filename (and location) for our key pair, press
Enter
without entering a filename. - Password: Enter a password that contains at least five characters, and then press Enter. If we press
Enter
without entering a password, our private key will be generated without password protection.
Our private key will be generated using the default filename (for example, id_rsa
) or the filename we specified (for example, my_ssh_key
), and stored on your computer in a .ssh
directory off our home directory (for example, ~/.ssh/id_rsa
or ~/.ssh/my_ssh_key
).
The corresponding public key will be generated using the same filename (but with a .pub extension added) and stored in the same location (for example, ~/.ssh/id_rsa.pub
or ~/.ssh/my_ssh_key.pub
).
Install the public key in remote server
To achieve this task, we can use either ssh-copy-id or scp command. The key we're going to install on remote server is the public one (e.g., ~/.ssh/id_rsa.pub
). This key or file should be stored on the remote server.
Using ssh-copy-id
Assuming you saved the key pair using the default file name and location, the structure for this command is like below:
$ ssh-copy-id -i ~/.ssh/id_rsa.pub jason@server
If not, replace the key path ~/.ssh/id_rsa.pub
above with your own key name. Adjust jason@server
as necessary. The output of above command should be similar with below:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/jason/.ssh/id_rsa.pub"
/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
jason@server's password:
Enter your user account password for that SSH server when prompted. If the authentication succeeded, it will respond with something like below:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'jason@server'"
and check to make sure that only the key(s) you wanted were added.
NOTE: On some system
ssh-copy-id
command may not be installed. If this is the case, we can usescp
method.
Using scp
The command for scp
method is fairly simple:
$ scp ~/.ssh/id_rsa.pub
jason
@server
You'll be prompted for your account password. Your public key will be copied to your home directory (and saved with the same filename) on the remote system.
Test key-based authentication
If you have successfully completed above procedures, you should be able to log into the remote host without the remote account’s password.
$ ssh jason@server
If your private key is password-protected, the remote system will prompt you for the password or passphrase (your private key password/passphrase is not transmitted to the remote system):
$ ssh jason@server
Enter passphrase for key '/home/jason/.ssh/id_rsa':
If your private key is not password-protected, the remote system will place you on the command line in your home directory without prompting you for a password or passphrase.
If you're able to logging in to your remote server, then we're ready to our next step: disabling password-based authentication entirely.
Add ourselves to administrative group
Before disabling password-based authentication completely, we need to make sure that we have SSH key-based authentication configured for an account on this server with sudo
access. This step will lock down password-based logins, so ensuring that you have will still be able to get administrative access is essential.
On our remote server, enter these command (jason
is my username):
$ id jason
As usual, adjust jason
with your own username. If the command result is:
uid=1000(jason) gid=1000(jason) groups=1000(jason)
Then you need to add yourself to sudo
group. This can be done by issuing this command:
$ sudo usermod -aG sudo jason
Remember to change jason
with your username. Next, verify that we've successfully added our username to sudo group:
$ id jason
The system should respond with something like this:
uid=1000(jason) gid=1000(jason) groups=1000(jason),27(sudo)
If that's the case, we can continue with next chapter.
Disable password login
Log into your remote server with SSH keys, either as root or with an account with sudo
privileges. Open the SSH daemon’s configuration file:
$ sudo vi /etc/ssh/sshd_config
Inside the file, search for a directive called PasswordAuthentication
. In my file it's on line 58.
...snip
56
57 # To disable tunneled clear text passwords, change to no here!
58 #PasswordAuthentication yes
59 #PermitEmptyPasswords no
60
...snip
Remove comment on the line and set the value to "no". This will disable your ability to log in through SSH using account passwords:
...snip
56
57 # To disable tunneled clear text passwords, change to no here!
58 PasswordAuthentication no
59 #PermitEmptyPasswords no
60
...snip
Save and close the file (Esc - :wq) when you are finished. To actually implement the changes we just made, you must restart the service.
On Ubuntu or Debian machines, you can issue this command:
$ sudo systemctl restart sshd
Optional: Disable root login
To make our system more secure, we can also disable root login via SSH.
Open our sshd_config file:
$ sudo vi /etc/ssh/sshd_config
Inside the file, search for a directive called PermitRootLogin
. In my file it's on line 34.
...snip
33 #LoginGraceTime 2m
34 PermitRootLogin yes
35 #StrictModes yes
...snip
And change it to no
...snip
33 #LoginGraceTime 2m
34 PermitRootLogin no
35 #StrictModes yes
...snip
Save the file and restart sshd
service using this command:
$ sudo systemctl restart sshd
Final Words
I hope that you now know how to configure SSH key-based authentication on Ubuntu 20.04 server. If you run into any issues or have any feedback feel free to drop a comment below.