SSH is one of the highly used tool by system admins and devops guys to access a remote server. SSH allows a user to access a remote system securely. SSH was made as a replacement for the older technologies like telnet and rsh(These older technologies used to send sensitive information like passwords in cleartext.)

The main problem with a protocol that sends information in cleartext is that anybody in the middle can read the communication by simply packet capturing.

The default authentication mechanism used by SSH is password based(with the simple workflow of using a ssh client to connect to a remote server, the server demands for a password, the user enters the password, and completes the authentication). Although passwords and other details sent over the wire in ssh is encrypted, it’s not recommended to use password based authentication mechanism. The primary reason behind this is the fact that password based authentication can easily be compromised using dictionary based brute force attacks.

Although you can add an additional layer of security to ssh by using services like fail2ban, it’s always better to disable password based authentication, and only accept public key based authentication.

How Key based Authentication in SSH Work?

Key based authentication involves two keys. One is called a private key and the other is called a public key. Basically a user creates these keys in pairs (with public and private key counterpart.)

The basic idea is…

Things encrypted using the SSH Public key can only be decrypted using ssh private key.

Some important things to note about ssh key based authentication.

  • You can share ssh public key to as many people and servers as possible (ie: you can share it to the places that you need access to using the private key counterpart)
  • SSH private key must be kept absolutely secret. In fact you should ideally encrypt the ssh private key further to prevent somebody else accessing it rather than you.

Above shown diagram depicts an overview of main steps taken by an ssh client and server, to establish authentication using public key mechanism.

How to generate an SSH Key pair?

Generating an ssh key pair in Linux is really simple. It only involves one single command called “ssh-keygen”.

#ssh-keygen

Generating public/private rsa key pair.

Enter file in which to save the key (/home/vmcentral/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/vmcentral/.ssh/id_rsa.

Your public key has been saved in /home/vmcentral/.ssh/id_rsa.pub.

The key fingerprint is:

69:50:31:d6:b8:91:1c:39:63:b5:f2:ec:f2:5e:55:9d vmcentral@docker-workstation.mc.spe.sony.com

The key’s randomart image is:

+–[ RSA 2048]—-+

|       .*O.      |

|       oX…    o|

|      …=.    Eo|

|       ..=     . |

|        S o   .  |

|       . .   .   |

|        . . .    |

|         o .     |

|         .o      |

+—————–+

The above produced randomart image is not of much use, but only required if you want to visually verify and compare two keys (ie: its intended for humans to verify stuff)

Also, it’s clearly visible from the above command output that it generated two different keys. One key is called id_rsa.pub (which is public key), and the other is called id_rsa (which is the private secret key)

The password prompted during creating of keys is optional. You can actually keep it blank (but we recommend protecting your private key using a passphrase.)

By default ssh-keygen will save the public and private keys under .ssh directory (which is located at the home directory of the user executing the ssh-keygen command). You can actually change this to wherever you want the keys to be saved (as clearly visible from above command, which prompted location for the user to specify). The main advantage of keeping it in the default location is that ssh-client will automatically search in that location for private key, while authenticating to a target server. 

The main important thing to note here is about the permission set of .ssh directory, id_rsa private key. If you do not have proper permission set applied to .ssh and key files, authentication using that key will fail till you fix the permission set.

The permission should be as below(lets say bob is the username)..

  • drwx—— 2 bob bob   4096 Aug 20 10:27 .ssh/ (ie: 700 for .ssh directory)
  • -rw——- 1 bob bob 1675 Aug 20 10:27 id_rsa (ie: 600 only read/write for owner)

let’s imagine that you want to authenticate to a target server using this key pair. The steps that you will take will be below.

Step 1:

Copy the contents of the file id_rsa.pub to the target server. The content should be copied to a special file in the target server (at .ssh directory located in the home directory of a target user, using which you will authenticate.)

Let’s say i have a user named “sysad” on all of my servers(this user will be used by all my system administrators to gain access).

In this case all of my system administrators will create an ssh key pair(as shown earlier, with ssh-keygen command), and copy the contents of  ~.ssh/id_rsa.pub to a special file called authorized_keys on the target server, inside “sysad” user home directory @ ~.ssh/authorized_keys

This means that all those users whose public keys are inside the file ~.ssh/authorized_keys of “sysad” user, will be able to login to the server using username “sysad”.

Is there any Alternative way to copy ssh public key to target server(rather than the manual one described above)? 

The simplest alternative method is using a ssh copy tool. The tool is called

#ssh-copy-id sysad@remote-server-ip

The above command will copy the user’s (well the user who runs that command) .ssh/id_rsa.pub file to target server (at sysad user’s home directory .ssh/authorized_keys)

Note: The above command expects that you know the password of sysad user to copy public key

Once the above command succeeds, you should be able to login to the target server using ssh sysad@remote-server-ip without password.

How to secure a target server to only accept key based authentication.?

You can easily modify the ssh server configuration file to completely disable password based authentication. This can be done by modifying ssh server configuration file (/etc/ssh/sshd_config)

PasswordAuthentication no

ChallengeResponseAuthentication no

UsePAM no

PermitRootLogin no

Once the above modification is done, simply restart ssh service on the server. Once after the restart you can easily confirm if password authentication is permitted (basically if you try to authenticate to the remote server, without a key, it will straight away deny access with the below error.)

Permission denied (publickey).