Configuring SSH Key-based Authentication
Objectives
After completing this section, you should be able to configure a user account to use key-based authentication to log in to remote systems securely without a password.
SSH Key-based Authentication
You can configure an SSH server to allow you to authenticate without a password by using keybased authentication. This is based on a private-public key scheme.
To do this, you generate a matched pair of cryptographic key files. One is a private key, the other a matching public key. The private key file is used as the authentication credential and, like a password, must be kept secret and secure. The public key is copied to systems the user wants to connect to, and is used to verify the private key. The public key does not need to be secret.
You put a copy of the public key in your account on the server. When you try to log in, the SSH server can use the public key to issue a challenge that can only be correctly answered by using the private key. As a result, your ssh client can automatically authenticate your login to the server with your unique copy of the private key. This allows you to securely access systems in a way that doesn't require you to enter a password interactively every time.
Generating SSH Keys
To create a private key and matching public key for authentication, use the ssh-keygen command. By default, your private and public keys are saved in your ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub files, respectively.
[rehan@localhost ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/rehan/.ssh/id_rsa): Enter
Enter passphrase (empty for no passphrase): Enter
Enter same passphrase again: Enter
Your identification has been saved in /home/rehan/.ssh/id_rsa
Your public key has been saved in /home/rehan/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:2TbxqP/1VtwPZzTJFouKJODtw4/C0QzwOaEoJa0w8Nk rehan@localhost.localdomain
The key's randomart image is:
+---[RSA 3072]----+
|o. |
|+.o+ o . |
|.=+ E = . o +|
|o. . * o + + . *.|
|. B S * o .oo|
| . * + o . *|
| . . = .+o|
| o . o . .o|
| . ... ..|
+----[SHA256]-----+
If you do not specify a passphrase when ssh-keygen prompts you, the generated private key is not protected. In this case, anyone with your private key file could use it for authentication. If you set a passphrase, then you will need to enter that passphrase when you use the private key for authentication. (Therefore, you would be using the private key's passphrase rather than your password on the remote host to authenticate.)
You can run a helper program called ssh-agent which can temporarily cache your private key passphrase in memory at the start of your session to get true passwordless authentication. This will be discussed later in this section.
The following example of the ssh-keygen command shows the creation of the passphraseprotected private key alongside the public key
[rehan@localhost ~]$ ssh-keygen -f .ssh/key-with-pass
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 1234
Enter same passphrase again: 1234
Your identification has been saved in .ssh/key-with-pass
Your public key has been saved in .ssh/key-with-pass.pub
The key fingerprint is:
SHA256:GjaoQCixVzrt7Vr9Wf4v8pEknIUOXfZJN3eFWCz62B8 rehan@localhost.localdomain
The key's randomart image is:
+---[RSA 3072]----+
|. . +++*|
|.o + .o++.*|
|+.+ . ..o....|
|o. o o .+ o |
|. o = S += . |
| . . o = . ooE. |
| . + . ..o. |
| o . +. o. |
| . o .+oo.|
+----[SHA256]-----+
[rehan@localhost ~]$ ls .ssh/
id_rsa key-with-pass known_hosts
id_rsa.pub key-with-pass.pub known_hosts.old
Sharing the Public Key
Before key-based authentication can be used, the public key needs to be copied to the destination system. The ssh-copy-id command copies the public key of the SSH keypair to the destination system. If you omit the path to the public key file while running ssh-copy-id, it uses the default /home/user/.ssh/id_rsa.pub file.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/key-with-pass.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
rehan@172.16.70.23's password: 1234
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'rehan@172.16.70.23'"
and check to make sure that only the key(s) you wanted were added.
After the public key is successfully transferred to a remote system, you can authenticate to the remote system using the corresponding private key while logging in to the remote system over SSH. If you omit the path to the private key file while running the ssh command, it uses the default /home/user/.ssh/id_rsa file.
[rehan@localhost ~]$ ssh -i .ssh/key-with-pass rehan@172.16.70.23
Enter passphrase for key '.ssh/key-with-pass': 1234
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Mon Jul 22 13:18:37 2024 from 172.16.70.22
[rehan@webserver ~]$
Sharing the Public Key (Windows Host to Linux Remote)
Generate an SSH Key on CMD
C:\Users\Monk>ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\Monk/.ssh/id_rsa):
C:\Users\Monk/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\Monk/.ssh/id_rsa
Your public key has been saved in C:\Users\Monk/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:Mt/vPGPVILfD8QED3C0iFEHBMw/rX9Me34oTWFrMxCY monk@LAPTOP-CPTQFMIT
The key's randomart image is:
+---[RSA 3072]----+
| +*=oo . |
| *Eo+= . |
| B*. + |
| . .* +. |
| o S = +.*.|
| + oo .o=oo|
| . o .oo.+|
| +=. .o|
| o=+.. |
+----[SHA256]-----+
Copy SSH Key to Remote Linux (PowerShell)
PS C:\Users\Monk> type $env:USERPROFILE\.ssh\id_rsa.pub | ssh operator1@servera_ip_address "cat >> .ssh/authorized_keys"
PS C:\Users\Monk> type $env:USERPROFILE\.ssh\id_rsa.pub | ssh operator1@172.16.70.30 "cat >> .ssh/authorized_keys"
operator1@172.16.70.30's password: redhat
Testing SSH From CMD
C:\Users\Monk>ssh operator1@servera_ip_address
Last login: Wed Jul 31 09:16:40 2024 from 172.16.70.24
[operator1@servera ~]$
Sharing the Public Key (Non Pass-phrase)
[rehan@localhost ~]$ ssh-copy-id -i .ssh/id_rsa.pub rehan@172.16.70.23
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".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
rehan@172.16.70.23's password:1234
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'rehan@172.16.70.23'"
and check to make sure that only the key(s) you wanted were added.
[rehan@localhost ~]$ ssh -i .ssh/id_rsa rehan@172.16.70.23
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Mon Jul 22 14:51:18 2024 from 172.16.70.22
[rehan@webserver ~]$
Using ssh-agent for Non-interactive Authentication
If your SSH private key is protected with a passphrase, you normally have to enter the passphrase to use the private key for authentication. However, you can use a program called ssh-agent to temporarily cache the passphrase in memory. Then any time that you use SSH to log in to another system with the private key, ssh-agent will automatically provide the passphrase for you. This is convenient, and can improve security by providing fewer opportunities for someone "shoulder surfing" to see you type the passphrase in.
Depending on your local system's configuration, if you initially log in to the GNOME graphical desktop environment, the ssh-agent program might automatically be started and configured for you. If you log in on a text console, log in using ssh, or use sudo or su, you will probably need to start ssh-agent manually for that session. You can do this with the following command:
Once ssh-agent is running, you need to tell it the passphrase for your private key or keys. You can do this with the ssh-add command.
The following ssh-add commands add the private keys from /home/user/.ssh/id_rsa (the default) and /home/user/.ssh/key-with-pass files, respectively.
[rehan@localhost ~]$ ssh-add
Identity added: /home/rehan/.ssh/id_rsa (rehan@localhost.localdomain)
[rehan@localhost ~]$ ssh-add .ssh/key-with-pass
Enter passphrase for .ssh/key-with-pass: 1234
Identity added: .ssh/key-with-pass (rehan@localhost.localdomain)
After successfully adding the private keys to the ssh-agent process, you can invoke an SSH connection using the ssh command. If you are using any private key file other than the default /home/user/.ssh/id_rsa file, then you must use the -i option with the ssh command to specify the path to the private key file.
The following example of the ssh command uses the default private key file to authenticate to an SSH server.
[rehan@localhost ~]$ ssh rehan@172.16.70.23
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Mon Jul 22 14:55:06 2024 from 172.16.70.22
[rehan@webserver ~]$
The following example of the ssh command uses the /home/user/.ssh/key-with-pass (non-default) private key file to authenticate to an SSH server. The private key in the following example has already been decrypted and added to its parent ssh-agent process, so the ssh command does not prompt you to decrypt the private key by interactively entering its passphrase.
[rehan@localhost ~]$ ssh -i .ssh/key-with-pass rehan@172.16.70.23
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Mon Jul 22 15:21:23 2024 from 172.16.70.22
[rehan@webserver ~]$
When you log out of the session that started ssh-agent, the process will exit and your the passphrases for your private keys will be cleared from memory.