Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 18, 2024
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.
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.
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.
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:
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.
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.
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.
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.
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:
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.
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.
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.
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.