1. Overview

When we connect to a new SSH server, the SSH client will usually prompt us, asking whether this action is ok. We may wish to prevent this from happening or ensure that the connection really is ok.

There are a few methods that we can use to connect to a new/unknown SSH server without getting the interactive question. In this tutorial, we’ll look at the method of adding a host public key to the known_hosts file to bypass the question.

2. Bypassing SSH Server Verification

SSH server verification is performed on the client side, where the SSH client prompts an interactive question whenever we try to connect to a new/unknown SSH server.

Let’s try connecting to an SSH server. We can use the Rebex SSH test server on port 22 with user ID demo and password password:

$ ssh [email protected]
The authenticity of host 'test.rebex.net (195.144.107.198)' can't be established.
ECDSA key fingerprint is SHA256:OzvpQxRUzSfV9F/ECMXbQ7B7zbK0aTngrhFCBUno65c.
Are you sure you want to continue connecting (yes/no)?

If we type yes, the SSH client writes the host public key to the known_hosts file and won’t prompt us again on the subsequent SSH connections to that host. If we don’t type yes, the connection is prevented.

2.1. The Purpose of SSH Server Verification

SSH server verification uses public key cryptography during the SSH handshaking process to verify the identity of the server. This ensures that we connect to the correct/intended host, and as a result, prevents the man-in-the-middle attack.

2.2. The Purpose of Bypassing SSH Server Verification

There are a couple of common reasons we might want to skip/bypass the interactive question that the SSH client prompts every time we connect to a new/unknown SSH server:

  • automation – we have scripts that do SSH, but we don’t want to handle the interactive question
  • security – we want to ensure that we connect only to correct/intended hosts, whose public keys we have verified

2.3. Bypassing SSH Server Verification at the Command Line

We can bypass the SSH client interactive question with a command-line switch:

$ ssh -o StrictHostKeyChecking=no test.rebex.net
Warning: Permanently added 'test.rebex.net,195.144.107.198' (ECDSA) to the list of known hosts.
Password: 
Welcome to Rebex Virtual Shell!
For a list of supported commands, type 'help'.
demo@ETNA:/$

The StrictHostKeyChecking flag’s default value is ask. If we set it to no, the SSH client will automatically add host keys to the known_hosts file and allow connections to hosts.

2.4. Bypassing SSH Server Verification by Configuration

We can add keys to /etc/ssh/ssh_config to disable SSH verification for all hosts:

$ cat /etc/ssh/ssh_config
...
Host *
StrictHostKeyChecking no
...
$ ssh [email protected]
Warning: Permanently added 'test.rebex.net,195.144.107.198' (ECDSA) to the list of known hosts.
Password:
Welcome to Rebex Virtual Shell!
For a list of supported commands, type 'help'.
demo@ETNA:/$

However, bypassing the checks can be very unsafe. Let’s look at how to use the host checking mechanism to help us.

3. Adding a Host Public Key to the known_hosts File

As the known_hosts file is the mechanism the SSH client uses to detect the correct identity of a remote server, we need to edit this file.

3.1. Adding a Host Public Key to the known_hosts File

To add a public key to our known_hosts file, we need to find it from the server. We can scan the host’s public key using ssh-keyscan:

$ ssh-keyscan test.rebex.net
# test.rebex.net:22 SSH-2.0-RebexSSH_5.0.8062.0
test.rebex.net ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAkRM6RxDdi3uAGogR3nsQMpmt43X4WnwgMzs8VkwUCqikewxqk4U7EyUSOUeT3CoUNOtywrkNbH83e6/yQgzc3M8i/eDzYtXaNGcKyLfy3Ci6XOwiLLOx1z2AGvvTXln1RXtve+Tn1RTr1BhXVh2cUYbiuVtTWqbEgErT20n4GWD4wv7FhkDbLXNi8DX07F9v7+jH67i0kyGm+E3rE+SaCMRo3zXE6VO+ijcm9HdVxfltQwOYLfuPXM2t5aUSfa96KJcA0I4RCMzA/8Dl9hXGfbWdbD2hK1ZQ1pLvvpNPPyKKjPZcMpOznprbg+jIlsZMWIHt7mq2OJXSdruhRrGzZw==
# test.rebex.net:22 SSH-2.0-RebexSSH_5.0.8062.0
test.rebex.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLZcZopPvkxYERubWeSrWOSHpxJdR14WFVES/Q3hFguTn6L+0EANqYcbRXhGBUV6SjR7SaxZACXSxOzgCtG4kwc=
# test.rebex.net:22 SSH-2.0-RebexSSH_5.0.8062.0
test.rebex.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOdXzF+Jx/wvEBun5fxi8FQK30miLZFND0rxkYwNcYlE

Let’s use the public key with ssh-rsa key type. We can add this line to the known_hosts file:

test.rebex.net ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAkRM6RxDdi3uAGogR3nsQMpmt43X4WnwgMzs8VkwUCqikewxqk4U7EyUSOUeT3CoUNOtywrkNbH83e6/yQgzc3M8i/eDzYtXaNGcKyLfy3Ci6XOwiLLOx1z2AGvvTXln1RXtve+Tn1RTr1BhXVh2cUYbiuVtTWqbEgErT20n4GWD4wv7FhkDbLXNi8DX07F9v7+jH67i0kyGm+E3rE+SaCMRo3zXE6VO+ijcm9HdVxfltQwOYLfuPXM2t5aUSfa96KJcA0I4RCMzA/8Dl9hXGfbWdbD2hK1ZQ1pLvvpNPPyKKjPZcMpOznprbg+jIlsZMWIHt7mq2OJXSdruhRrGzZw==

After adding the line, we should be able to SSH to test.rebex.net without interruption.

We should note that if the SSH client still prompts us, we may need to check the HashKnownHosts config parameter.

3.2. Hashing Hostnames

If the value of the HashKnownHosts config parameter in /etc/ssh/ssh_config is yes, we need to hash all hostnames in the known_hosts file, which we can easily do by using ssh-keygen:

Before:

$ cat .ssh/known_hosts
...
|1|x/FU+XU7O/fk/ifF4cFTKYHO62U=|vopK8lRpcCYqdUY4a+ZFfNc5B4U= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsQNaXMM12Zk2CeKzO2rhc2wCY+NbAzWHE8I8P37Si4Biiu4Ye0kNIc88WEw707PjIpVEXzks0WtrQLb1LMDP0=
202.157.184.104 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDvwlIAnK9+WSW7dEC4axK5VoAOC9Yt5FqRYLq8hTd33k08AkbzuNCrJoYfdksqqlp9qjiMlcDkhO/IccnFU1fe7tEzTMR/1AAuR+AvZoa6tVEUxDC3spZEWmH3AVGi4fQGY2jReCOxt6Ie07QSoyMpwDYfYidjryAn6pfFoUX8B5EyHzYrQU6kyGOeQTqXx+L1lg8/uH6RmiS5DlH3JPq4cJqKxGTW7zGBf8dDnZfZd/eiXReLoNK8HnPotIhNxxn4rPCRKzEyyFb9tOsc5hXqo6Ff3d+ajmMImZi+izpf8y84WSbeNkDjVlo0ONzyY3azi0Owlq6ac5toLnP6YJf1

$ ssh-keygen -Hf ~/.ssh/known_hosts
/home/baeldung/.ssh/known_hosts updated.
Original contents retained as /home/baeldung/.ssh/known_hosts.old
WARNING: /home/baeldung/.ssh/known_hosts.old contains unhashed entries
Delete this file to ensure privacy of hostnames

After:

$ cat .ssh/known_hosts
...
|1|x/FU+XU7O/fk/ifF4cFTKYHO62U=|vopK8lRpcCYqdUY4a+ZFfNc5B4U= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsQNaXMM12Zk2CeKzO2rhc2wCY+NbAzWHE8I8P37Si4Biiu4Ye0kNIc88WEw707PjIpVEXzks0WtrQLb1LMDP0=
|1|tF6s1ZUMS0dGxbag7b91a4MWisY=|tZw73FGyIJyNL80IP95b1CJYgiI= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOWSOyEv30pi0M/jB6m/2HLG+gIqaT1WN6GXJPbIaYyz/EFBRP57C+xM08R0/GJKvszINJUylFm1LYT+TOoPlvU=

Let’s review the parameters that we have to use for ssh-keygen:

  • H – hash a known_hosts file, which consequently will replace all hostnames and addresses with hashed representations
  • f – filename of the key file

Once we’ve hashed the hostnames, we should be able to connect to the SSH host without interruption. However, if the SSH client still prompts us, we may need to use a different host public key.

3.3. Selecting a Host Public Key Type

The OpenSSH client has a priority order of the public key types defined by the HostKeyAlgorithms config parameter in /etc/ssh/ssh_config:

If we’ve added the ssh-rsa key type to the known_hosts file but we’re still getting the interactive question, we can try adding the host public key with the ecdsa-sha2-nistp* key type:

test.rebex.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLZcZopPvkxYERubWeSrWOSHpxJdR14WFVES/Q3hFguTn6L+0EANqYcbRXhGBUV6SjR7SaxZACXSxOzgCtG4kwc=

We must remember that if the HashKnownHosts config parameter in /etc/ssh/ssh_config is set to yes, we need to hash the hostnames using ssh-keygen:

$ ssh-keygen -Hf ~/.ssh/known_hosts
/home/baeldung/.ssh/known_hosts updated.
Original contents retained as /home/baeldung/.ssh/known_hosts.old
WARNING: /home/baeldung/.ssh/known_hosts.old contains unhashed entries
Delete this file to ensure privacy of hostnames

At this point, we should be able to connect to the SSH server without the prompt. Otherwise, we might need to check the SSH server to ensure that it’s been configured correctly.

3.4. Adding All Host Public Keys to the known_hosts File

As a quick tip, instead of selecting and adding the host public keys one by one, we can add all host public keys to the known_hosts file:

$ ssh-keyscan test.rebex.net >> ~/.ssh/known_hosts

Similarly, if the HashKnownHosts parameter is set to yes, we can pass the -H parameter to automatically hash the hostnames:

$ ssh-keyscan -H test.rebex.net >> ~/.ssh/known_hosts

This command appends all test.rebex.net public keys with hashed hostnames to the known_hosts file.

4. Conclusion

In this article, we looked at the process of adding a host public key to the known_hosts file.

Besides adding the public key, we also checked if we needed to hash the host names and select the host public key type.

Moreover, by having keys in the known_host files, we can bypass the host verification question and ensure we connect to the correct host.