When a CentOS Stream 9 system is first installed, it is configured by default to allow remote command-line access via Secure Shell (SSH) connections. SSH provides password-protected and encrypted access to the system for the root account and any other users added during the installation phase. However, this level of security is inadequate and should be upgraded to SSH key-based authentication as soon as possible.
This chapter will outline the steps to increase the security of a CentOS 9 system by implementing key-based SSH authentication.
An Overview of Secure Shell (SSH)
SSH allows secure remote access to systems to gain shell access and transfer files and data. As will be covered in CentOS Stream 9 Remote Desktop Access with VNC, SSH can also provide a secure tunnel through which remote access to the GNOME desktop can be achieved over a network connection.
A basic SSH configuration consists of a client (used on the computer establishing the connection) and a server (running on the system to which the connection is to be established). A user might, for example, use an SSH client running on a Linux, Windows, or macOS system to connect to the SSH server running on a CentOS 9 system to gain access to a shell command-line prompt or to perform file transfers. All communications between the client and server, including the password entered to gain access, are encrypted to prevent outside parties from intercepting the data.
The inherent weakness in a basic SSH implementation is that it depends entirely on the strength of the passwords assigned to the accounts on the system. If a malicious party can identify the password for an account (either through guesswork, deception, or a brute force attack), the system becomes vulnerable. This weakness can be addressed by implementing SSH key-based authentication.
SSH Key-based Authentication
SSH key-based authentication uses asymmetric public key encryption to add an extra layer of security to remote system access. The concept of public key encryption was devised in 1975 by Whitfield Diffie and Martin Hellman and is based on using a pair of private and public keys. In a public key encryption system, the public key is used to encrypt data that can only be decrypted by the owner of the private key.
In the case of SSH key-based authentication, the host holds the private key on which the SSH client is located, while the corresponding public key resides on the system on which the SSH server is running. Therefore, it is vital to protect the private key since ownership of the key will allow anyone to log into the remote system. As an added layer of protection, the private key may also be encrypted and protected by a password which must be entered each time a connection is established to the server.
Setting Up Key-based Authentication
There are four steps to setting up key-based SSH authentication, which can be summarized as follows:
- Generate the public and private keys.
- Install the public key on the server.
- Test authentication.
- Disable password-based authentication on the server.
The remainder of this chapter will outline these steps in greater detail for Linux, macOS, and Windows-based client operating systems.
Installing and Starting the SSH Service
If the SSH server is not already installed and running on the system, it can be added using the following commands:
# dnf install openssh-server # systemctl start sshd.service # systemctl enable sshd.serviceCode language: plaintext (plaintext)
SSH Key-based Authentication from Linux and macOS Clients
The first step in setting up SSH key-based authentication is to generate the key pairs on the client system. If the client system is running Linux or macOS, this is achieved using the ssh-keygen utility:
ssh-keygenCode language: Shell Session (shell)
This command will result in output similar to the following:
Generating public/private rsa key pair. Enter file in which to save the key (/home/<username>/.ssh/id_rsa):Code language: plaintext (plaintext)
Press the Enter key to accept the default location for the key files. This will place two files in the .ssh sub-directory of the current user’s home directory. The private key will be stored in a file named id_rsa while the public key will reside in the file named id_rsa.pub.
Next, ssh-keygen will prompt for a passphrase with which to protect the private key. If a passphrase is provided, the private key will be encrypted on the local disk, and the passphrase will be required to access the remote system. Therefore, for better security, the use of a passphrase is recommended.
Enter passphrase (empty for no passphrase):Code language: plaintext (plaintext)
Finally, the ssh-keygen tool will generate the following output indicating that the keys have been generated:
Your identification has been saved in /home/neil/.ssh/id_rsa. Your public key has been saved in /home/neil/.ssh/id_rsa.pub. The key fingerprint is: SHA256:FOLGWEEGFIjWnCT5wtTOv5VK4hdimzWghZizUEMYbfo <username>@<hostname> The key’s randomart image is: +---[RSA 2048]----+ |.BB+=+*.. | |o+B= * . . | |===.. + . | |*+ * . . | |.++ o S | |..E+ * o | | o B * | | + + | | . | +----[SHA256]-----+Code language: plaintext (plaintext)
The next step is to install the public key onto the remote server system. This can be achieved using the ssh-copy-id utility as follows:
ssh-copy-id username@remote_hostnameCode language: Shell Session (shell)
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/neil/.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 [email protected]’s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added.Code language: plaintext (plaintext)
Once the key is installed, test that the authentication works by attempting a remote login using the ssh client:
$ ssh -l <username> <hostname>Code language: plaintext (plaintext)
If the private key is encrypted and protected with a passphrase, enter the phrase when prompted to complete the authentication and establish remote access to the CentOS 9 system:
Enter passphrase for key '/home/neil/.ssh/id_rsa': Last login: Fri Mar 31 14:29:28 2023 from 192.168.86.21 [neil@demosystem02 ~]$Code language: plaintext (plaintext)
Repeat these steps for any other accounts on the server for which remote access is required. If access is also required from other client systems, copy the id_rsa private key file to the .ssh subdirectory of your home folder on the other systems.
As currently configured, access to the remote system can still be achieved using less secure password authentication. Once you have verified that key-based authentication works, password authentication must be disabled on the system. To understand how to change this setting, begin by opening the /etc/ssh/sshd_config file and locating the following line:
Include /etc/ssh/sshd_config.d/*.confCode language: plaintext (plaintext)
This tells us that sshd configuration settings are controlled by files in the /etc/ssh/sshd_config.d directory. These filenames must be prefixed with a number and have a .conf filename extension, for example:
01-permitrootlogin.conf 50-redhat.confCode language: plaintext (plaintext)
The number prefix designates the priority assigned to the file relative to the other files in the folder, with 01 being the highest priority. This ensures that if a configuration file contains a setting conflicting with another file, the one with the highest priority will always take precedence. Within the /etc/ssh/sshd_config.d folder, create a new file named 02-nopasswordlogin.conf with content that reads as follows:
PasswordAuthentication noCode language: plaintext (plaintext)
Save the file and restart the sshd service to implement the change:
# systemctl restart sshd.serviceCode language: plaintext (plaintext)
From this point on, it will only be possible to remotely access the system using SSH key-based authentication, and when doing so, you won’t be required to enter a password.
Managing Multiple Keys
It is common for multiple private keys to reside on a client system, each providing access to a different server. As a result, several options exist for selecting a specific key when establishing a connection. It is possible, for example, to specify the private key file to be used when launching the ssh client as follows:
$ ssh -l neilsmyth -i ~/.ssh/id_work 126.96.36.199Code language: plaintext (plaintext)
Alternatively, the SSH client user configuration file may associate key files with servers. The configuration file is named config, must reside in the .ssh directory of the user’s home directory, and can be used to configure a wide range of options, including the private key file, the default port to use when connecting, the default user name, and an abbreviated nickname via which to reference the server. The following example config file defines different key files for two servers and allows them to be referenced by the nicknames home and work. In the case of the work system, the file also specifies the user name to be used when authenticating:
Host work HostName 188.8.131.52 IdentityFile ~/.ssh/id_work User neilsmyth Host home HostName 192.168.0.21 IdentityFile ~/.ssh/id_homeCode language: plaintext (plaintext)
Before setting up the configuration file, the user would have used the following command to connect to the work system:
$ ssh -l neilsmyth -i ~/.ssh/id_work 184.108.40.206Code language: plaintext (plaintext)
Now, however, the command can be shortened as follows:
ssh workCode language: Shell Session (shell)
A full listing of configuration file options can be found by running the following command:
$ man ssh_configCode language: plaintext (plaintext)
SSH Key-based Authentication from Windows Clients
Recent releases of Windows include a subset of the OpenSSH implementation used by most Linux and macOS systems as part of Windows PowerShell. This allows SSH key-based authentication to be set up from a Windows client using similar steps to those outlined above for Linux and macOS.
On Windows, search for Windows PowerShell and select it from the results. Once running, the PowerShell window will appear as shown in Figure 15-1:
If you already have a private key from another client system, copy the id_rsa file to a folder named .ssh on the Windows system. Once the file is in place, test the authentication within the PowerShell window as follows:
$ ssh -l <username>@<hostname>Code language: plaintext (plaintext)
PS C:\Users\neil> ssh -l neil 192.168.1.101 Enter passphrase for key 'C:\Users\neil\.ssh\id_rsa':Code language: PowerShell (powershell)
Enter the passphrase when prompted and complete the authentication process.
If the private key does not yet exist, generate a new private and public key pair within the PowerShell window using the ssh-keygen utility using the same steps outlined for Linux and macOS. Once the keys have been generated, they will again be located in the .ssh directory of the current user’s home folder, and the public key file id_rsa.pub will need to be installed on the remote CentOS Stream 9 system. Unfortunately, Windows PowerShell does not include the ssh-copy-id utility, so this task must be performed manually.
Within the PowerShell window, change directory into the .ssh sub-directory and display the content of the public key id_rsa.pub file:
PS C:\Users\neil> cd .ssh PS C:\Users\neil\.ssh> type id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFgx1vzu59lll6/uQw7FbmKVsQ3fzLz9MW1fgo4sdsxXp81wCHNAlqcjx1Pgr9BJPXWUMInQOi7BQ5I+vc2xQ2AS0kMq3ZH9ybWuQe/U2GjueXZd0FKrEXrT55wM36Rm6Ii3roUCoGCzGR8mn95JvRB3VtCyDdzTWSi8JBpK5gV5oOxNTNPsewlLzouBlCT1qW3CKwEiIwu8S9MTL7m3nrcaNeLewTTHevvHw4QDwzFQ+B0PDg96fzsYoTXVhzyHSWyo6H0gqrft7aK+gILBtEIhWTkSVEMAzy1piKtCr1IYTmVK6engv0aoGtMUq6FnOeGp5FjvKkF4aQkh1QR28r neil@DESKTOP-S8P8D3NCode language: plaintext (plaintext)
Once signed in, check if the .ssh sub-directory exists. If it does not, create it as follows:
mkdir .sshCode language: Shell Session (shell)
Change directory into .ssh and check whether a file named authorized_keys already exists. If it does not, create it and paste the content of the public key file from the Windows system into it.
If the authorized_keys file already exists, it likely contains other keys. If this is the case, edit the file and paste the new public key at the end of the file. The following file, for example, contains two keys:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzRWH27Xs8ZA5rIbZXKgxFY5XXauMv+6F5PljBLJ6j+9nkmykVe3GjZTp3oD+KMRbT2kTEPbDpFD67DNL0eiX2ZuEEiYsxZfGCRCPBGYmQttFRHEAFnlS1Jx/G4W5UNKvhAXWyMwDEKiWvqTVy6syB2Ritoak+D/Sc8nJflQ6dtw0jBs+S7Aim8TPfgpi4p5XJGruXNRScamk68NgnPfTL3vT726EuABCk6C934KARd+/AXa8/5rNOh4ETPstjBRfFJ0tpmsWWhhNEnwJRqS2LD0ug7E3yFI2qsNKGEzvAYUC8Up45MRP7liR3aMlCBil1tsy9R+IB7oMEycZAe/qj [email protected] ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFgx1vzu59lll6/uQw7FbmKVsQ3fzLz9MW1fgo4sdsxXp81wCHNAlqcjx1Pgr9BJPXWUMInQOi7BQ5I+vc2xQ2AS0kMq3ZH9ybWuQe/U2GjueXZd0FKrEXrT55wM36Rm6Ii3roUCoGCzGR8mn95JvRB3VtCyDdzTWSi8JBpK5gV5oOxNTNPsewlLzouBlCT1qW3CKwEiIwu8S9MTL7m3nrcaNeLewTTHevvHw4QDwzFQ+B0PDg96fzsYoTXVhzyHSWyo6H0gqrft7aK+gILBtEIhWTkSVEMAzy1piKtCr1IYTmVK6engv0aoGtMUq6FnOeGp5FjvKkF4aQkh1QR28r neil@DESKTOP-S8P8D3NCode language: plaintext (plaintext)
Once the public key is installed on the server, test the authentication by logging in to the server from within the PowerShell window, for example:
PS C:\Users\neil\.ssh> ssh -l neil 192.168.1.100 Enter passphrase for key 'C:\Users\neil\.ssh\id_rsa':Code language: plaintext (plaintext)
When key-based authentication has been set up for all the accounts and verified, disable password authentication on the CentOS 9 system as outlined at the end of the previous section.
SSH Key-based Authentication using PuTTY
For Windows systems that do not have OpenSSH available or as a more flexible alternative to using PowerShell, the PuTTY tool is a widely used alternative. The first step in using PuTTY is downloading and installing it on any Windows system that needs an SSH client. PuTTY is a free utility and can be downloaded using the following link:
Download the Windows installer executable that matches your Windows system (32-bit and 64-bit versions are available), then execute the installer to complete the installation.
If a private key exists on another system, create the .ssh folder in the current user’s home folder and copy the private id_rsa key into it.
Next, the private key file must be converted to a PuTTY private key format file using the PuTTYgen tool. Locate this utility by typing “PuTTY Key Generator” into the search bar of the Windows Start menu and launch it:
Once launched, click on the Load button located in the Actions section and navigate to the private key file previously copied to the .ssh folder (note that it may be necessary to change the file type filter to All Files (*.*) for the key file to be visible). Once located, select the file and load it into PuttyGen. When prompted, enter the passphrase used initially to encrypt the file. Once the private key has been imported, save it as a PuTTY key file by clicking the Save Private Key button. For consistency, save the key file to the .ssh folder but give it a different name to differentiate it from the original key file.
Launch PuTTY from the Start menu and enter the IP address or hostname of the remote server into the main screen before selecting the Connection -> SSH -> Auth -> Credentials category in the left-hand panel, as highlighted in Figure 15-3:
Click the Browse button next to the Private key for authentication field and navigate to and select the previously saved PuTTY private key file. Then, optionally, scroll to the top of the left-hand panel, select the Session entry, and enter a name for the session in the Saved Sessions field before clicking on the Save button. This will save the session configuration for future use without reentering the settings each time.
Finally, click on the Open button to establish the connection to the remote server, entering the user name and passphrase when prompted to do so to complete the authentication.
Generating a Private Key with PuTTYgen
The previous section explored using existing private and public keys when working with PuTTY. If keys do not exist, they can be created using the PuTTYgen tool, included in the main PuTTY installation.
To create new keys, launch PuttyGen and click on the Generate button highlighted in Figure 15-4:
Move the mouse pointer to generate random data as instructed, then enter an optional passphrase to encrypt the private key. Once the keys have been generated, save the files to suitable locations using the Save public key and Save private key buttons. As outlined in the previous section, the private key can be used with PuTTY. To install the public key on the remote server, use the steps covered in the earlier section on SSH within PowerShell on Windows.
Any remote access to a CentOS Stream 9 system must be implemented in a way that provides a high level of security. By default, SSH allows remote system access using password-based authentication. However, this leaves the system vulnerable to anyone who can guess a password or find out the password through other means. For this reason, key-based authentication is recommended to protect system access. Key-based authentication uses public key encryption involving public and private keys. When implemented, users can only connect to a server using a client with a private key that matches a public key on the server. As an added layer of security, the private key may also be encrypted and password protected. Once key-based encryption has been implemented, the server system is configured to disable support for the less secure password-based authentication.
This chapter has provided an overview of SSH key-based authentication and outlined the steps involved in generating keys and configuring clients on macOS, Linux, and Windows, as well as installing and managing public keys on a CentOS Stream 9 server.