Skip to main content

SSH - How to use public key authentication on Linux


  • Please read the whole post before you start. This will help you avoid a lock-out

Generating a secure key pair

SSH keys use asymmetric cryptographic algorithms that generate a pair of separate keys (a key pair). A private and a public key.

We are using the command ssh-keygen to generate our secure key pair. There are 3 common algorithms to choose from.

We are going to create a private and public key with the name nameofthekey in the .ssh directory of the current user. You should choose a expressive name, which makes it easier to work with multiple keys. Please make sure that the directory ~/.ssh/ exists.

Important: Please do use a secure password for the key generation.

RSA (Rivest–Shamir–Adleman)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/nameofthekey
ECDSA (Elliptic Curve Digital Signature Algorithm)
ssh-keygen -t ecdsa -b 521 -f key1 ~/.ssh/nameofthekey
EdDSA ed25519:
ssh-keygen -t ed25519 -f ~/.ssh/nameofthekey
ssh-keygen # can be run as a standard user, man ssh-keygen for more information
-t [dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa] # choose Algorithm
-b bits # number of bits to use
-f /path/and/name-of-keypair # choose a name for the keys
ssh-keygen -t rsa -b 4096 -f ~/.ssh/nameofthekey

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in name
Your public key has been saved in
The key fingerprint is:
SHA256:8KkCBz2GFXusy6URXF4Z/8xVl+6dFhYV0MoDtqIqBfA kuser@pleasejustwork
The key's randomart image is:
+---[RSA 4096]----+
|    o.. oo   .o.B|
| . = = ... o   =.|
|  = B =   o + + .|
|   E = o o = = + |
|  . = . S . + + +|
|   + * o       +.|
|    * o       .  |
|   . o           |
|    .            |

This would give us 2 files: private key nameofthekey, and public key - public key


ssh-rsa ktLfCNsABzCw9wE4U3JS8mn1t8jw2Q01wRvCaexpuE2adZYxgw4sNJfBOp3SmLEYeF3rcP1u9ffb2J8FOqFWj3egwjVvVrlDHwi6Jr1aTxOmNlGtNHfJiKuJxD3HxPFAuSImsR5IZF6Bki0LxQGxM4jx8NgDFQ5BWO0tJ0pNzSJdXOLwW0jqbdqdEHELnYZLmll6oeJ9j1LZx6GY5vjYxzeCxZTrHoFQPE2vdYsx7ajIKDzQpNdM9zhYRO10OM kuser@pleasejustwork

nameofthekey - private, password protected



The correct permissions on the client

It is important to have the correct permissions for your key. For 2 reasons: restrict the access of other users, and some servers require it, when the 'StrictModes' is enabled. Later more.

sudo chmod 700 ~/.ssh
sudo chmod 644 ~/.ssh/authorized_keys
sudo chmod 644 ~/.ssh/known_hosts
sudo chmod 644 ~/.ssh/config
sudo chmod 600 ~/.ssh/nameofthekey        # private key
sudo chmod 644 ~/.ssh/    # public key

Get your public key on the server

You need access to the destination server in one way or another to add the newly generated public key. There are multiple ways.

In the end, the public key must be added to the ~/.ssh/authorized_keys file. If it does not exist, it must be created. There can be multiple public keys in this file - one line per key, and there can be multiple authorized_keys, IF it is configured on the server.

No direct access to the server

Ask someone with access to add your public key to the ~/.ssh/authorized_keys file.

Direct access via ssh and password auth

You most likely already have access to the server via ssh and normal password authentication. There are now multiple ways to add your public key to the server.

Simply use ssh-copy-id:
ssh-copy-id -i ~/.ssh/ remote-user@remote-server
This does everything for you, and adds your public key to the authorized_keys file on the remote machine.

Different way would be to copy the public key to the remote machine via scp / rsync, or something different, and redirect >> it to ~/.ssh/authorized_keys. Another way would be to connect to the server, and copy-paste the content of the public key to ~/.ssh/authorized_keys. Remember, if the path or file does not exist, just create it.

In the end, your chosen public key must be in the file ~/.ssh/authorized_keys before you should continue.

Configuration of the ssh server

Important: Some tips on how to work on the configuration file on the remote machine.

  • do a backup of the configuration file before you do any changes!
  • create 2 ssh sessions - 1 for working and testing, the other one as a backup.
  • reload the config of the ssh server, rather than restarting the service. This does not kill the backup session.
  • test the public key authentication before you turn off password authentication

We now have to edit the ssh server config file on the remote machine: /etc/ssh/sshd_config or in the config directory /etc/ssh/sshd_conf.d. It depends on your setup.

Enabling public key authentication on the server
Enable public key authentication in the config file:
PubkeyAuthentication yes
Now, reload the config of the ssh server. Assuming you are using systemd:
sudo systemctl reload sshd
Before we continue, please do try to connect to the remote machine with your ssh key:
ssh -i ~/.ssh/nameofthekey remote-user@remote-server # choose the private key!
enter the password for your private key, and you should be connected.
Enable the strict mode
Open the sshd_config file and add:
StrictModes yes
this makes sure, that the permissions are correct on the client side. You won't be able to connect to the server, if the permissions are not correct!
Now, reload the config of the ssh server:
sudo systemctl reload sshd

Important: Please test the connection once more!

If you successfully connected to the remote machine, you can proceed to turn off password authentication.

Disable password authentication

Last chance: make sure that you have tested the public key authentication, and / or have another option to access the machine.

Open the sshd_config file and change one option:
PasswordAuthentication no

This will disable the possibility to authenticate with a password, but you should still be able to log in with your public key, after reloading the config.

Reload the config of the ssh server:
sudo systemctl reload sshd

This should be it!

More SSH hardening options can be found here.


Some debugging options on client:
-v / -vv / -vvv
ssh -vvv -i ~/.ssh/nameofthekey remote-user@remote-server
Some debugging options on server:
sudo journalctl -u ssh
sudo grep ip.of.your.machine /var/log/auth.log
You can change the log level of the server by editing the config file:
LogLevel INFO # default
LogLevel DEBUG # enable DEBUG mode

Don't forget to turn it off again before it fills up your storage.

Manage private key identities with an agent

Nobody wants to enter their password for the private key every time they want to connect to a server. By using ssh-add - the OpenSSH auth agent - you can add your private key once for the session, and do not have to enter your private key password every time.

Check for identities:
ssh-add -L
Add private key identity:
ssh-add ~/.ssh/nameofthekey # choose the private key and enter the password
Remove all identities:
ssh-add -D
If you run into:
Could not open a connection to your authentication agent.

Just run eval "$(ssh-agent)" OR `eval ssh-agent` and right after exec ssh-agent bash. This restarts the agent and sets the correct environment variables from my understanding.

E-Mail hellofoo@ittafoovern.comcom

More reading: