Bobcares

SSH Servers, Clients and Keys – A detailed analysis

by | Mar 27, 2021

Wondering what is SSH Servers, Clients and Keys? Here’s all you need to know.

The most common way of connecting to a remote Linux server is through SSH. It provides a safe and secure way of executing commands, making changes, and configuring services remotely.

As part of our Server Management Services, we assist our customers with several SSH queries.

Today, let us discuss SSH Servers, Clients, and Keys.

 

How SSH Works

We drop into a shell session when we connect through SSH, where we can interact with the server. The commands we type are sent through an encrypted SSH tunnel to execute on the server.

The SSH connection implements using a client-server model. Hence, the remote machine must run a piece of software called an SSH daemon.

It will listen for connections on a specific network port, authenticate connection requests, and spawn the appropriate environment if the user provides the correct credentials.

In addition, the user computer should have an SSH client. This will have information about the remote host to connect to the username to use, and the credentials to authenticate.

 

How SSH Authenticates Users

Most of our clients authenticate using passwords or SSH keys. Our Support Techs prefer SSH keys since they are very secure.

SSH keys are a matching set of cryptographic keys which we can use for authentication. Each set contains a public key that can be shared freely without concern and a private key that should be vigilantly guarded and never exposed to anyone.

To authenticate using SSH keys, a user must have an SSH key pair on their local computer. On the remote server, we must copy the public key to a file within the user’s home directory at ~/.ssh/authorized_keys.

When we connect to the host to use SSH key authentication, it will inform the server of this intent and the public key to use.

Later, the server checks its authorized_keys file for the public key, generates a random string, and encrypts it using the public key. Only with the associate private key, we can decrypt this message.

Once the recipient decrypts the message it generates an MD5 hash of this value and transmits it back to the server.

The server already has the original message and the session ID, so it can compare an MD5 hash generated by those values and determine that the client must have the private key.

 

SSH Servers, Clients, and Keys

In this article, let us see some common ways of connecting with SSH along with what is SSH Servers, Clients, and Keys.

 

SSH Keys

Let us see how to generate SSH keys on a client machine and distribute the public key to servers to use.

  • Generating an SSH Key Pair

It is the first step towards authenticating with a remote server without a password. Our Support Techs recommend authenticating using SSH keys.

We use a number of cryptographic algorithms to generate SSH keys, including RSA, DSA, and ECDSA.

Generally, we prefer the RSA keys and it is the default key type.

To generate an RSA key pair, we run:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):

It allows us to choose the location to store the RSA private key.

To leave this as the default, press ENTER and it will store them in the .ssh hidden directory in the user’s home directory. The default location will allow the SSH client to find the keys automatically.

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Then we enter a passphrase of an arbitrary length to secure the private key. By default, we have to enter the passphrase we set here every time we use the private key, as an additional security measure.

While we enter a passphrase, nothing will display as we type.

This is a security precaution.

Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
8c:e9:7c:fa:bf:c4:e5:9c:c9:b8:60:1f:fe:1c:d3:8a root@here
The key’s randomart image is:
+–[ RSA 2048]—-+
| |
| |
| |
| + |
| o S . |
| o . * + |
| o + = O . |
| + = = + |
| ….Eo+ |
+—————–+

This procedure generates an RSA SSH key pair, located in the .ssh hidden directory within the user’s home directory. These files are:

  1. ~/.ssh/id_rsa: The private key. DO NOT SHARE THIS FILE!
  2. ~/.ssh/id_rsa.pub: The associated public key. This can be shared freely without consequence.
  • Generate an SSH Key Pair with a Larger Number of Bits

By default, the SSH keys are 2048 bits. Though it’s good enough, we can specify a greater number for a more hardened key.

To do this, we include the -b argument with the number of bits we like. Most servers support at least 4096 bits. However, longer keys may not accept for DDOS protection purposes:

$ ssh-keygen -b 4096

If we already have a different key, we can overwrite the previous one:

Overwrite (y/n)?

If we choose “yes”, the previous key will be overwritten and we can no longer log in to servers using that key.

  • Remove or Change the Passphrase on a Private Key

In case we wish to change or remove the paraphrase, we can do it easily.

To do so, we run:

$ ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa):

We can give the location of the key to modify or press ENTER to accept the default value:

Enter old passphrase:

After we provide the old password, we will have a prompt for the new:

Enter new passphrase (empty for no passphrase):
Enter same passphrase again:

Here, enter the new passphrase or press ENTER to remove the passphrase.

  • SSH Key Fingerprint

Generally, each SSH key pair share a single cryptographic “fingerprint” to uniquely identify the keys.

To find out the fingerprint of an SSH key, we run:

$ ssh-keygen -l
Enter file in which the key is (/root/.ssh/id_rsa):

We can press ENTER if that is the correct location of the key, else enter the revised location.

In addition, we will have a string that contains the bit-length of the key, the fingerprint, and account and hosts it was created for, and the algorithm:

4096 8e:c4:82:47:87:c2:26:4b:68:ff:96:1a:39:62:9e:4e demo@test (RSA)
  • Copy the Public SSH Key to a Server with SSH-Copy-ID

If we have password-based SSH access to the server, and we have the ssh-copy-id utility installed, this is a simple process.

With this option, we can easily transfer the public key:

$ ssh-copy-id username@remote_host

This will prompt us for the user account’s password on the remote system:

The authenticity of host ‘111.111.11.111 (111.111.11.111)’ can’t be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed — if you are prompted now it is to install the new keys
demo@111.111.11.111’s password:

Then, the contents of the ~/.ssh/id_rsa.pub key will append to the end of the user account’s ~/.ssh/authorized_keys file:

Number of key(s) added: 1

Now try logging into the machine, with: “ssh ‘demo@111.111.11.111′”
and check to make sure that only the key(s) you wanted were added.

We can now log in to that account without a password:

$ ssh username@remote_host
  • Copy the Public SSH Key to a Server Without SSH-Copy-ID

If we have password-based SSH access to the remote server and no ssh-copy-id utility, we can copy the contents of the public key in a different way.

We can output the contents of the key and pipe it into the ssh command. On the remote side, we can ensure that the ~/.ssh directory exists, and then append the piped contents into the ~/.ssh/authorized_keys file:

$ cat ~/.ssh/id_rsa.pub | ssh username@remote_host “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys”
The authenticity of host ‘111.111.11.111 (111.111.11.111)’ can’t be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
demo@111.111.11.111’s password:

After entering the password, the key will copy, allowing to log in without a password:

$ ssh username@remote_IP_host
  • Copy the Public SSH Key to a Server Manually

If we do not have password-based SSH access available, we have to add the public key to the remote server manually.

We can find the contents of the public key file by typing:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== demo@test

We can copy this value, and manually paste it into the appropriate location on the remote server.

Then on the remote server, create the ~/.ssh directory if it does not already exist:

$ mkdir -p ~/.ssh

Afterward, we create or append the ~/.ssh/authorized_keys file by typing:

$ echo public_key_string >> ~/.ssh/authorized_keys

Now, we will be able to log in without a password.

 

Server-Side Configuration Options

Now let us look at a few server-side configuration options that can shape the way the server responds and the types of connections allowed.

  • Disable Password Authentication

If we have SSH keys configured, tested, and working properly, it is good to disable password authentication.

To do this, connect to your remote server and open the /etc/ssh/sshd_config file with root or Sudo privileges:

$ sudo nano /etc/ssh/sshd_config

Inside the file, search for the PasswordAuthentication directive. If it is commented out, uncomment it. Set it to no to disable password logins:

PasswordAuthentication no

Once done, save and close the file. To implement the changes, we restart the SSH service.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart

Now, all accounts on the system will be unable to log in with SSH using passwords.

  • Change the Port that the SSH Daemon Runs On

Sometimes, it is better to change the default port that SSH runs on. This will help decrease the number of authentication attempts from bots.

In order to do that, log in to the remote server. Then open the sshd_config file on the remote system with root privileges:

$ sudo nano /etc/ssh/sshd_config

Once inside, we can change the port that SSH runs on by finding the Port 22 specification and modifying it to reflect the port we need.

For instance, to change the port to 4444, we add:

#Port 22
Port 4444

Eventually, save and close the file. To implement the changes, we restart the SSH daemon.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart

After the daemon restarts, we will need to authenticate by specifying the port number.

  • Limit the Users Who can Connect Through SSH

For this, we can take a few different approaches, each of which involves editing the SSH daemon config file.

On the remote server, open the below file with root or sudo privileges:

$ sudo nano /etc/ssh/sshd_config

The first method is the AllowUsers directive.

Search for the AllowUsers directive in the file. If it does not exist, we create it anywhere.

After the directive, list the user accounts that should be allowed to login through SSH:

AllowUsers user1 user2

Eventually, save and close the file. Then, we restart the daemon to implement changes.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart

In addition, we can use the AllowGroups directive instead. If so, just add a single group that should be allowed SSH access:

AllowGroups sshmembers

Then, save and close the file.

Now, we can create a system group matching the group we specified by typing:

$ sudo groupadd -r sshmembers

Make sure to add whatever user accounts we need to this group:

$ sudo usermod -a -G sshmembers user1
$ sudo usermod -a -G sshmembers user2

Later, restart the SSH daemon to implement changes.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart
  • Disable Root Login

Our Support Techs advice to completely disable root login through SSH once we set up an SSH user account that has sudo privileges.

For that, open the SSH daemon configuration file with root or sudo on your remote server:

$ sudo nano /etc/ssh/sshd_config

Inside, search for a directive called PermitRootLogin. If it is commented, uncomment it. Change the value to “no”:

PermitRootLogin no

Save and close the file. To implement changes, we restart the SSH daemon.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart
  • Allow Root Access for Specific Commands

At times, we might want to disable root access generally, but enable it in order to allow certain applications to run correctly.

For instance, for a backup routine.

We can do it through the root user’s authorized_keys file, which contains SSH keys that are authorized to use the account.

Add the key from the local computer that we wish to use to the root user’s authorized_keys file on the server.

We will demonstrate with the ssh-copy-id command here:

$ ssh-copy-id root@remote_host

Then, log into the remote server. To adjust the entry in the authorized_keys file, open it with root or sudo access:

$ sudo nano /root/.ssh/authorized_keys

At the beginning of the line with the key we upload, add a command= listing that defines the command that this key is valid for. This should include the full path to the executable, plus any arguments:

command=”/path/to/command arg1 arg2″ ssh-rsa …

Once done, save and close.

Now, open the sshd_config file with root or sudo privileges:

$ sudo nano /etc/ssh/sshd_config

Find the directive PermitRootLogin, and change the value to forced-commands-only:

PermitRootLogin forced-commands-only

Eventually, save and close the file. Restart the SSH daemon to implement changes.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart
  • Forward X Application Displays to the Client

We can configure the SSH daemon to automatically forward the display of X applications on the server to the client machine. For this to function correctly, the client must configure and enable an X windows system.

To enable, login to the remote server and edit the sshd_config file as root or with sudo privileges:

$ sudo nano /etc/ssh/sshd_config

Search for the X11Forwarding directive. If it is commented out, uncomment it. Create it if necessary and set the value to “yes”:

X11Forwarding yes

Save and close the file. Restart the SSH daemon to implement these changes.

On Ubuntu/Debian:

$ sudo service ssh restart

On CentOS/Fedora:

$ sudo service sshd restart

To connect to the server and forward an application’s display, we have to pass the -X option from the client upon connection:

$ ssh -X username@remote_host

Graphical applications started on the server through this session will display on the local computer.

 

Client-Side Configuration Options

Moving ahead, we will focus on some adjustments that we can make on the client-side of the connection.

  • Define Server-Specific Connection Information

On the local computer, we can define individual configurations for some or all of the servers we connect to. We can store it in the ~/.ssh/config file, which is read by the SSH client each time it is called.

Initially, create or open this file in a text editor on the local computer:

$ nano ~/.ssh/config

Inside, we can define individual configuration options by introducing each with a Host keyword, followed by an alias.

For example,

Host testhost
HostName your_domain
Port 4444
User demo

Then we connect to your_domain on port 4444 using the username demo:

$ ssh testhost

We can also use wildcards to match more than one host.

Make note that later matches can override earlier ones. So, we should put the most general matches at the top.

For instance, we could default all connections to not allow X forwarding, with an override for your_domain by having this in your file:

Host *
ForwardX11 no

Host testhost
HostName your_domain
ForwardX11 yes
Port 4444
User demo

Eventually, save and close the file.

  • Keep Connections Alive to Avoid Timeout

If in case we disconnect from SSH sessions before we are ready, it is possible that the connection is timing out.

We can configure the client to send a packet to the server every so often in order to avoid this situation:

We can configure this in the ~/.ssh/config file. Open it now:

$ nano ~/.ssh/config

If one does not already exist, at the top of the file, define a section that will match all hosts. Set the ServerAliveInterval to “120” to send a packet to the server every two minutes.

This is enough to notify the server not to close the connection:

Host *
ServerAliveInterval 120

Eventually, save and close the file.

  • Disable Host Checking

By default, when we connect to a new server, we can see the remote SSH daemon’s host key fingerprint.

The authenticity of host ‘111.111.11.111 (111.111.11.111)’ can’t be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

This is to verify the authenticity of the host we are attempting to connect to and spot malicious instances.

In certain circumstances, we may wish to disable this feature. This can be a big security risk.

To make the change, open the ~/.ssh/config file on the local computer:

$ nano ~/.ssh/config

If one does not already exist, at the top of the file, define a section that will match all hosts.

Set the StrictHostKeyChecking directive to no to add new hosts automatically to the known_hosts file. Set the UserKnownHostsFile to /dev/null to not warn on new or changed hosts:

Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

Then we can enable the checking on a case-by-case basis by reversing those options for other hosts. The default for StrictHostKeyChecking is ask:

Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

Host testhost
HostName your_domain
StrictHostKeyChecking ask
UserKnownHostsFile /home/demo/.ssh/known_hosts

[Need help with the process? We are here for you]

 

Conclusion

In short, the above instructions by our Support Techs cover the majority of the information about SSH Servers, Clients and Keys.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = "owonCMyG5nEQ0aD71QM";

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Never again lose customers to poor
server speed! Let us help you.