A guide, I wish I had, when I started learning SSH.

Introduction

The SSH command consists of 3 distinct parts:

ssh {user}@{host}

{user} represents the account you want to access.

{host} refers to the computer you want to access. This can be an IP Address or a domain name

ssh ubuntu@x.x.x.x or ssh ubuntu@test.com

SSH protocol uses symmetric encryption, asymmetric encryption and hashing in order to secure transmission of information. The SSH connection between the client and the server happens in three stages:

  1. Verification of the server by the client.
  2. Generation of a session key to encrypt all the communication.
  3. Authentication of the client.

Verification of the server by the client

If a user unknowingly logs in to a malicious server, who ever has control of that server could easily acquire that user’s login credentials and then use those credentials to gain access to the legitimate server. Secondly, if the unwitting user uploads files to the malicious server, those files will surely fall into the wrong hands. Lastly, if a user downloads files from the server, that user could end up downloading malware.

Server authentication helps prevent these from happening because if the authentication process fails, the client will be given an appropriate warning.

In order to perform ssh authentification. We’ve two important files : known-hosts and authorized_keys

Generation of a session key to encrypt all the communication

Authentication of the client

After symmetric encryption has been established, the authentication of the client happens as follows:

  1. The client begins by sending an ID for the key pair it would like to authenticate with to the server.
  2. The server checks the authorized_keys file of the account that the client is attempting to log into for the key ID.
  3. If a public key with matching ID is found in the file, the server generates a random number and uses the public key to encrypt the number and sends this encrypted message.
  4. If the client has the correct private key, it will decrypt the message to obtain the random number that was generated by the server.
  5. The client combines the obtained random number with the shared session key and calculates the MD5 hash of this value.
  6. The client then sends this MD5 hash back to the server as an answer to the encrypted number message.
  7. The server uses the same shared session key and the original number that it sent to the client to calculate the MD5 value on its own. It compares its own calculation to the one that the client sent back. If these two values match, it proves that the client was in possession of the private key and the client is authenticated.

Asymmetry of the keys allows authentication of the client because client can only decrypt the messages if it has the correct associated private key.

Required SSH Files

Authorized keys file

The system admin can run this command to install your public key on the remote server youre trying to connect to :

ssh-copy-id -f -i id_rsa.pub ubuntu@x.x.x.x

Known-hosts file

Fingerprints are used in order to verify the server’s identity based on his hashed public key and also to verify that the client’s private key matches the client’s public key on the server which means that the client is connected to the right server that already have the client’s public key installed.

Well, you may be wondering. How does all of these work ?

The first time a user connects to the remote SSH server, he’ll be presented with the server’s fingerprint. To verify, the user can contact the system admin that can dictate to him the record of the fingerprint. If they match, the user can then store that fingerprint in the known-hosts file for future login sessions.Once a fingerprint is saved, the client can automatically look up that fingerprint every time it connects to the server. If a match is made, the client will know it's connecting to a server it had already connected to before.

It’s therefore very important to make sure all fingerprints the client saves have already been manually verified. If you accept a fingerprint without verifying, especially if you’re connecting to a remote server, you might end up storing a fingerprint of a malicious server.

How to obtain the server’s fingerprint if you’re a system admin ?

The quickest way to obtain it would be to login to your SSH server from a locally installed client application, i.e. installed on the same machine as your server. That way, you can be absolutely sure you’re safe from man-in-the-middle attacks. Connect using SSH and then save the displayed fingerprint where you can easily access it.

You can also use this tool :

ssh-keygen -lf /path/to/public_key/pubkey_in_openssh_format.pub

Being a visual learner myself, here is an image of an overview of the SSH Authentification Process :

In order to go further , There are some cases when we may lost our private key. To know what should we do in such a case, check the link.

It’s worth noting that a key pair (the private and public keys) will have the same fingerprint; so in the case you can’t remember which private key belong to which public key, find the match by comparing their fingerprints or by running commands such as :

ssh-keygen -y -e -f <private key>

Which will generate the corresponding public key.

Setting Up SSH

Step 1 : Generate the client’s keyPairs

ssh-keygen -t rsa -b 2048 -C "client@example.com"

The client’s public and private key will be stored in ssh/id_rsa.pub and ssh/id_rsa respectively

Step 2 : The admin system should copy the client’s public key to the remote server in .ssh/authorized_keys file

ssh-copy-id -f -i id_rsa.pub ubuntu@x.x.x.x

Step 3 : The client can then connect to the remote server

ssh ubuntu@x.x.x.x

You can also create a config file .ssh/config where you define credentials to the remote server :

Host remote-server
Hostname x.x.x.x
User ubuntu
IdentityFile ~/.ssh/id_rsa

Note that ~/.ssh/id_rsa is the private key that corresponds to the user’s public key on the server.

References