Skip to main content

SSH Public Key Authentication

By December 18, 2019September 12th, 2022No Comments

RHCSA 8 Study Guide

Let me introduce you to how you can implement SSH Public Key Authentication for your clients to remote SSH servers in readiness for your RHCSA exam. Although the SSH server would normally be a remote server we demonstrate this with a single server for both the SSH client and SSH server. The process is the same and enables your to follow through the lab and learning with just a single system.


When connecting to Linux via SSH we can use SSH Public Key Authentication to our servers, this is often the default for cloud based servers such as AWS. Using password based authentication is adequate but is not the most secure for our clients. It also can be tiresome to have to type the password each time you connect, especially if copying files with scp. Another option is to use key based authentication for you clients. This way the client authenticates to their private key and the public key is used to authenticate to servers. We delve into SSH public key authentication in this blog and video.

Firstly, we need to generate a public key and private key pair for the client. Working on the client we use ssh-keygen for this.

$ ssh-keygen -t ecdsa
Generating public/private ecdsa key pair.
Enter file in which to save the key (/home/tux/.ssh/id_ecdsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/tux/.ssh/id_ecdsa.
Your public key has been saved in /home/tux/.ssh/
The key fingerprint is:
The key's randomart image is:
+---[ECDSA 256]---+
|o...++==o        |
|=oo+ .==++ E     |
|+*+.  .o+.. .    |
|Bo. o. .         |
|+* . .. S        |
|Oo.   .          |
|Bo.    .         |
|o. . .  .        |
|  ....o.         |

Using the type of ecdsa, we set to a more secure key than the default rsa. I have added a passphrase to secure the private key. I could have been left blank is that meets your security requirements. Having a passphrase means that we still need to add the phrase during authentication but you will learn to cache this.

Next, we need to copy the public key to the server and user that we want to authenticate to. The file will be added to the target user’s home directory and the file $HOME/.ssh/authorized_keys. We will copy to the root user’s directory so we can authenticate as root.

$ ssh-copy-id -i ~/.ssh/ root@localhost
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/tux/.ssh/"
/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
root@localhost's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@localhost'"
and check to make sure that only the key(s) you wanted were added.


We simply, copy the file the remote location, we do not have a remote shell and we are left on the local system. We can now test the effectiveness of the key but authenticating again:
$ ssh root@localhost 
Enter passphrase for key '/home/tux/.ssh/id_ecdsa': 
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Fri Nov  8 15:41:21 2019 from ::1

We connect to the remote server as root after we authenticate to the local private key. We can check from the remote server that the key is stored in the root user’s home directory.

# cat .ssh/authorized_keys 
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBmgU9kA3Fr2E2obQ+K4UOWfxRMS1lbDz/dMrK4VFHDIGqCqyfldOB5GweA+3Ii85qv/ThmEdWUV+APsTfHpZ5s=

Yes, it is there!

Finally, we need to cache the password for the private key. We will exit back to the client. Once on the client we will use ssh-agent to cache the password.

# exit
Connection to localhost closed.
$ eval $(ssh-agent)
Agent pid 5322
$ ssh-add 
Enter passphrase for /home/tux/.ssh/id_ecdsa: 
Identity added: /home/tux/.ssh/id_ecdsa (
$ ssh root@localhost
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Fri Nov  8 15:42:32 2019 from ::1
[root@rhel8 ~]#

Once we have authenticated to the ID with the agent, the password is stored within the shell for future use. As we use ssh, scp or sftp to the remote system as root, we are not prompted for the password. We can choose now the raise the security on the remote system perhaps only allowing root to login if the client has pre-shared their public key. On the remote system, we can edit the /etc/ssh/sshd_config. We will use sed to affect the edit making sure that we test the result first. As the results are verbose to be able to easily see the result we use -n to supress the standard output and the command p at the end of the regular expression to print the matching pattern:

# sed -n 's/^PermitRootLogin yes/PermitRootLogin without-password/p' /etc/ssh/sshd_config
PermitRootLogin without-password

When we are happy with the result we can then make the edit, make sure you remove the p at the end of the regular expression and change the option -n to -i.

# sed -i 's/^PermitRootLogin yes/PermitRootLogin without-password/' /etc/ssh/sshd_config
# systemctl restart sshd

With the change and restart in-place. We cannot login as the root user using a password. We have to use key based authentication or Kerberos. Using SSH, as well as having the central client configuration file /etc/ssh_config we can add a local client configuration: ~/.ssh/config. We can simplify the login to a remote system by storing hostnames, options and keys in the file:

$ cd ; umask 077
$ cat > .ssh/config <<END
> Host my_host
>   IdentityFile ~/.ssh/id_ecdsa
>   HostName localhost
>   User root

From the home directory of a local client system we set the umask to ensure new files are priave to use. It is required by SSH that the config file we create is private to the user. We then populate the file. We can now use the host entry my_host as a shortcut to connect to the remote system:

$ ssh my_host
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Fri Nov  8 15:48:29 2019 from ::1

Online Instructor Led Training

As we have moved through this blog we have seen how we can use SSH public key authentication for our remote clients, adding their public key to the target users .ssh/authorized_keys file on the remote server. With this in place we can help secure our server by disabling Password based authentication.