Friday, March 1, 2024

Difference between known_hosts and authorized_keys file in SSH - Linux

If you have used SSH to login into remote host in Linux, you might have come across these two files stored under the .ssh directory in your home directory e.g. ~/.ssh. Both files are used in the login process for authentication, but the main difference between known_hosts and authorized_keys files are that, known_host is used for server authentication, while authorized_keys are used for client or user authentication. SSH allows login using both password and private keys, you might have heard about trusted SSH connection between two host to download files without entering password, this is achieved using public and private keys. 

For example, when a user from host A (client) do the SSH to host B (server) then the host B (server) sends its's public key to the host A, if that key is present in the known_hosts then SSH doesn't prompt user about authenticating server, but if doesn't exist then it prints message "The authenticity of host 'dev2323pgm (10.62.32.22)' can't be established" and asks user to confirm the identity of server by using RSA fingerprint, a short form of public key of server. 

Once user confirm that server is the one he wants to connect, SSH adds that server into known_hosts and next time it doesn't prompt user to confirm server identity.

Now, some of you might be wondering, what is the need here to confirm the identity of Server? isn't it we given IP address to connect to the server? If IP address is correct then we must be connecting to the right server. 

Well, many things can happen e.g. redirection or Man-In-The-Middle-Attack, which intercept your message and printed to be the server. Before you send your confidential information e.g. password, you must confirm the identity of the Server.

On the other hand authorized_keys are used to authenticate clients connecting to the server. This file holds a list of authorized public keys for hosts. When the client connects to a server, the server authenticates the client by checking its signed public key stored within this file.

So, if you want to setup password less login or non-interactive login between two servers using SSH, then you must copy the public key of client into the authorized_key file of server.


When you connect to a new host using SSH, you receive following message:

]$ ssh dev2323pgm
The authenticity of host 'dev2323pgm (10.62.32.22)' can't be established.
RSA key fingerprint is 6a:64:e6:4e:23:42:dd:e6:ca:d5:99:96:43:6a:eb:76.
Are you sure you want to continue connecting (yes/no)?



If you say yes, then public key of this host will be added into your .ssh/known_hosts file and next time when you do SSH to this host, it will not print this message. This is part of server authentication, first time, you manually authenticate the server by verifying its RSA key fingerprint, which is a short sequence of bytes used to identify a longer public key. 

Next time, SSH automatically checks if server's public key is present in known_hosts or not, if yes, then it authenticate the server and confirm the server is the one who it claims and allows you to enter password for client authentication.


Warning: Permanently added 'dev2323pgm,110.62.32.22' (RSA) to the list of known hosts.


You can verify that by checking the .ssh/known_hosts file as shown below:


$ cat ~/.ssh/known_hosts
dev2323pgm,110.62.32.22 ssh-rsa MIGfMA0565GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wV3QZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp40GbMJDyR4e9T04ZZwIDAQAB



Next time when you will login to same host using same user, SSH will not ask you to verify the identity of the server again, instead it will directly point you for password. You can even do SSH login without password if public key of your machine is added into authorized_key file of server for the same user.




Important points about known_hosts and authorized_key in SSH

Here are few more important things which you should know and remember

1) In public key cryptography, there are a pair of keys, public keys and private key. The public key is something a user or host can share with third-party but he must keep the private key secret to himself. Since public key can be shared with third-party it is often used to authenticate the user. 

For example, when SSH connects to a server, the server sends it public key and SSH can authenticate the server if knows about its public key. Why authentication of Server is required? It is required to prevent Man-In-The-Middle-Attack where another host can be an imposter. 

For example, you are logging on your bank's website, before you enter your confidential credential e.g. username and password, you want to be 100% sure that you are connected to the real bank's website not the imposter server which look-a-like your bank website but controlled by someone else. The public key of bank website can be used to authenticate the server or website here.


2) Private key is usually longer then public key. You can share public keys to others but you must keep private key secret with you. Third-party can encrypt a message intented for you by using your public key which means that message can only be opened by you, by using your private key.


3) The SSH protocol allows you to both login using a password or public-private keys.


4) The known_hosts files stores list of servers which you have logged in from that hosts. It stores host, ip, and the public key of server as shown below:

$ cat ~/.ssh/known_hosts
dev2323pgm,110.62.32.22 ssh-rsa MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfX9J/DgYSF6vUpwmJG8wVQZkKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB



If an host is already exists in this file then SSH doesn't ask you to confirm its identity. Usually when you first login to a server from another server, you see that mesage, once you accept and move on, you don't see that message again because public key of that server is added on known_hosts file.


5) The authorized_key file is used to authenticate client connection. If a key corresponding to the client hosts exists in this file then server sends messages encrypted using public key of client host and then client can use its private key to decrypt those message. 

This way, you can also establish password-less SSH login between two hosts. You might have seen pair of trusted server where you can download files without entering your password. The same mechanism is used by SCP file copy protocol as well.


6) You can logging into a remote server by using private key and SSH. The ssh command allows you to specify your identity file using the -i option as shown below:


$ ssh -i private_key.txt demo@192.237.248.66


7) If you don't have a pair of keys then you can also generate them using the ssh-keygen command in Linux as shown below:


$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa): mykey
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in mykey.
Your public key has been saved in mykey.pub.
The key fingerprint is:
b3:6f:c9:e2:59:d0:81:af:11:4d:08:a2:f8:17:7f:c6 user1@demo.com



After executing command you will see two files in your .ssh folder:

mykey
mykey.pub


The first file contains the private key for you and second file contains the public key for you. You can use any encryption algorithm, RSA is default but by using $ ssh-keygen -t you can specify encryption algorith e.g. RSA or DSA.


If you want to enable password-less login from host A/user A to host B/user B then you must not enter a passphrase, when ssh-keygen command ask for it. Just leave it empty. If you don't provide any name then it will by default create an id_rsa and id_rsa.pub file in the host. 

The first one contains your private key and should stay with you while the second one contain your public key which you can pass to server to add into its list of authorized_keys. This will enable client to do SSH login without password on server.


You can also add public key of a server into your known host by using $ ssh-keygen -R demo.com
/home/user1/.ssh/known_hosts updated.
Original contents retained as /home/user1/.ssh/known_hosts.old


This command will add the public key of host 192.237.248.66 into known_hosts file.


8) You can also copy the public key of client into server by using the ssh-copy-id command e.g. ssh-copy-id user@server

Just replace user with your remote user and server with the DNS name or IP address of server. It'll prompt for your SSH password, enter it and if all completes successfully you'll be able to access the machine via ssh user@server without needing a password.

Also, here is a nice summary of how SSH login works, step by step



That's all about difference between authorized_keys and known_host file in SSH on Linux. In short, the known_host file is used to authenticate servers on client machine while auhtorized_keys file is used to authenticate client on server machine. In order to set up a password less login between two hosts in Linux using SSH, the public key of server must exists in the known_host of client and public key of client must exist in the authorized_key of server. 

Once you do this you can do SSH login without password, very useful if you are invoking ssh command from a shell script or Java program and automate file copy or something else.

2 comments :

CertDepot said...

There is an error at the beginning of your explanation: "For example, when a user from host A (client) do the SSH to host B (server) then the host B (server) sends its's public key to the host B ..." -> to the host A.

javin paul said...

Yes, it should be host A, thanks for pointing it out, somehow I overlooked it.

Post a Comment