10 useful steps to install and secure SSH server in Linux

SSH stands for Secure Shell, one of the well-known service protocols used to execute an operation to the remote administration over the internet. It provides a very secure passage between the designated computers. Once the connection is established, SSH will then provide encrypted sessions for all public (unsecured) networks in a client-server architecture. It was developed for the replacement of insecure remote protocols like "Telnet, rlogin, and rsh". As we know the drawbacks of using these insecure protocols, if someone used a third party packet capturing tools like ‘tcpdump and Wireshark’ between the designated computers can reveal the password and exploit the systems easily.

SSH services are deployed and used by millions of Servers in Data Centers around the world. These days shell accounts are much less used, but the protocol remains the same standard for operating systems where there is no physical access. SSH is one of the essential tools preferred by many System and Network Administrators is used for remote server management, but still, few users do prefer to use GUI tool. SSH packages are available mostly on all RHEL, CentOS, and Fedora OS by default and for other distros maybe not, in that case, you need to install the packages manually.

SSH Access methods:

There are two common methods used to access the (remote or local) server using SSH.

(i) Username and Password: This is the basic method of accessing the server, once you are connected to the server with a username, the server will be asked to verify your identity by providing the password. If the credentials are correct, then you will be granted access; or else it will be denied.

(ii) Public or Private keys: This is a very secure method of accessing the server, it doesn't require a password to access the server, but it needs a private key. Once the user is connected to the server using the correct private key, the server starts to perform a check whether the given key is correct or not. If the key is correct, the user will be granted access; or else it will be denied.

Encryption Techniques:

SSH offers an outstanding feature in encryption to transfer the data's between the server and the client. The client is nothing but a local computer where the SSH client package which is used to connect to the remote server via secure shell protocol and the server will be located at the remote location.

In SSH we can use three different types of encryption:

(a) Symmetrical Encryption

(b) Asymmetrical Encryption

(c) Hashing

Symmetric encryption: It is also called a shared key or secret encryption key. It helps for both encryption and decryption of data by client and server. Obtaining the key by anyone (client or server) can decrypt the message. In Symmetrical there are a variety of ciphers that exist, like AES, CAST128, Blowfish, RC4, etc. But the most used ones are AES-128, AES-192, and AES-256. The drawback of using this key encryption is that it will involve all the parties to exchange the key to encrypt the information before they can decrypt the same.

Asymmetrical Encryption: Asymmetrical uses two separate (public and private) keys for encryption and decryption. The combination of these two keys forms as key pair named "public-private key". The public key can be freely available or openly shared with any party, but the private key will be kept secret. The combination between these two keys is a bit difficult in terms of encryption and decryption, which means if a piece of information is encrypted by using a public key it can be used by only the private key to decrypt and vice-versa. Asymmetric encryption is the most used form of communication over the internet. It uses RSA, DSA,PKCS,etc.

Hashing: Hashing uses another form of cryptography to secure connections. It is a one-way process and completely different from the above forms of encryption, meaning hashed data is never meant to be decrypted. For more details about encryption, click here.

In real-time, to set up, the SSH server is one of the common tasks for every system administrator to access the servers remotely (Cloud VPS or Traditional Server). It is very simple to install and enable, but to configure and secure the SSH server is a bit tough and must know how to do it properly otherwise it can be easily hacked.

This step-by-step guide will help you how to install and secure your SSH server on RHEL / Centos 7 for a better remote administration over the internet. You can use the same guide for all the versions of RHEL/CentOS/Fedora with a few minimal changes.

Prerequisites :

Operating System      :    CentOS Linux 7 or higher version's
package                       :     openssh-server openssh-clients
User account              :     root user or user account with sudo privileges
Recommended to run all the administrative commands as with sudo privilege instead of root

Difficulties in setting up sudo users? Click here to find the steps.

My Lab Setup :

For the lab setup, I am using 2 centos machines. One for the server and the other one for the client.

SSH Server:

 

Operating System    :   CentOS Linux 7 (core)
Hostname                  :   sshs01.linuxteck
IP Address                 :  192.168.1.100

SSH Client:

 

Operating System      :    CentOS Linux 7 (core)
Hostname                    :    cli01.linuxteck
IP Address                   :   192.168.1.200
SSH client                    :   An active ssh client like " Terminal for Linux/Mac and Putty for Windows"

Step1: Install and enable SSH Server

First, let's update the latest current version and then install the SSH server and client. OpenSSH package is the most popular one and mostly these packages are installed by default, if not use the following command to install.

$ sudo yum update -y

 

$ sudo yum install -y openssh-server

Note:

The OpenSSH package is a free version of SSH. This package contains an init script called SysV to manage the OpenSSH Server. Now start, enable, and check the status of the sshd daemon using the following command.

$ sudo systemctl start sshd

 

$ sudo systemctl enable sshd

 

$ sudo systemctl status sshd

Note:

If the status shows as "active (running)", then the installation of your SSH server went well without any issues also you use the 'netstat' command to verify the port number. As you can see in the output below, it is only listening on the default port 22.
$ sudo netstat -tulnp | grep ssh
netstat command in linux

The main configuration file of the SSH server in Centos is located at "/etc/ssh/sshd_config". For any customization on the SSH server, we need to modify this file correctly. If you install the server-client package on the same server, then you can find a similar named file "ssh_config" in the "/etc/ssh" path as well, but don't get confused about these two files. (sshd_config is for SSH server and ssh_config is for SSH Clients)

If you want to know more about ssh client commands, you can have a look at this article on 10 basic and most useful 'ssh' client commands in Linux

Note:

It is always recommended to make a copy of the original configuration file before making any changes to it. If there are any issues, you can simply revert the changes to the default one.
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Step2: Enable SSH Protocol Version 2

By default, SSH protocols support versions 1 and 2 within a single daemon. As we know, version 1 has a lot of issues related to the security part and those have been updated in version2 especially the security and encryption, also it is not very compatible with version1. Hence, it is recommended to block the connections coming from version 1 clients. To make the changes, open your ssh config file and add the line "Protocol 2" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

Protocol 2

 

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

Save and exit.

Note:

For every change/modification in the "sshd_config" file, we need to restart the service to implement these changes. This server currently only accepts connections from only version 2 clients. You can do the test using the following command:

$ sudo ssh -1 john@192.168.1.100

Output:

 

SSH protocol v.1 is no longer supported

Note:

The above message clearly shows that the SSH protocol version 1 no longer supports the above Server. The above command (-1) specifies protocol version1. Now if you want to access the server, you need to use one of the following commands.

$ sudo ssh -2 john@192.168.1.100

 

$ sudo ssh john@192.168.1.100

Step 3: Customize the default SSH port (22)

As mentioned above, by default ssh used Port 22 for communication. Hackers are really smart and intelligent if they come to know if your server is using it as default and it will be easy for them to attack. To avoid this, we can customize the SSH port number. I am going to use Port 1875. To make the changes, open your ssh config file and scroll through the file until you see the line that starts with "#Port 22". Uncomment/remove the (#) from the beginning of the line. Now replace the line with "Port 1875" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

Port 1875
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

Save and exit.

Note:

After restarting the service, you can verify it through the client machine to access the default method of using port 22 and then test with port 1875.
$ sudo systemctl restart sshd
Output:
Job for sshd.service failed because the control process exited with error code. See "systemctl status sshd.service" and "journalctl -xe" for details.

WARNING:

SSH fails to restart after the port change in CentOS7. To make the ‘sshd’ to run after the port change we need to adjust the SELinux or disable it completely. I will disable it in our demo, but I highly recommend activating SELinux in production. To adjust SELinux, execute the following command:

$ sudo semanage port -a -t ssh_port_t -p tcp 1875

The above command will tell SELinux that the SSH service is now running on the new port 1875. Restart the sshd service and try to access it from the client using port 22 and port 1875.

$ sudo ssh john@192.168.1.100

Output:

ssh: connect to host 192.168.1.100 port 22: Connection refused

Note:

Here you can see that the ssh connection was completely rejected using port 22 and now try with our customized port 1875
$ sudo ssh -p 1875 john@192.168.1.100
Output:
ssh: connect to host 192.168.1.100 port 1875: No route to host

WARNING:

Again, the connection was refused. This time it shows as "No route to host". This is due to the firewall setup. You can either disable the firewall or permit port 1875 in the firewall for ssh. In our demo, we are going to add a new rule to permit the new port.
$ sudo firewall-cmd --permanent --add-port=1875/tcp

Note:

Once you have added a permanent rule to the firewall, make sure to restart the firewalld service to make those rules work in a permanent configuration.
$ sudo systemctl restart firewalld

If you want to know more about firewalld services, have a look at this article on 15 basic useful firewall-cmd commands in Linux.

You can now access your ssh server with port 1875.

$ sudo ssh -p 1875 john@192.168.1.100
john@192.168.1.100's password: xxxxxxxx

Note:

Finally, the connection is accepted!
Step4: Disable root login (SSH)

Using root accounts in SSH is quite dangerous especially on the public network. Hence, it is advised to disable the root login to your server. Before deleting/deactivating the root account, make sure you have a normal user on your server who has enough privileges to use sudo or su. To deactivate the root login, open your ssh config file and scroll through the file until you see the line that starts with "#PermitRootLogin yes". Uncomment/remove the (#) from the beginning of the line. Now replace the line with "PermitRootLogin no" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

Save and exit.

Note:

Restart the service. The root account has now been deactivated on the SSH Server.
Step 5: Use ssh keys (Public and Private)

In Linux, there are two common methods of accessing the SSH servers. The first one is using the password, and the second method is by using the SSH key (public & private). The second method is much more secure than the password method. We know that passwords can be cracked or brute-forced at any time by hackers, so it is recommended to use the SSH keys to access the server via remotely. Using the following command we can generate the ssh keys.

$ sudo ssh-keygen

ssh-keygen for linux server

Note:

While executing the above command, it will ask you to enter the path to save the key, or press enter to save the key to the default path or you can specify your path. Next, the system will ask you to "Enter passphrase (empty for no passphrase):", it is a choice only, either you enter the passphrase or leave it as blank, but it is highly recommended to enter the secure passphrase as it will give you an additional layer of security to prevent unauthorized access to your servers.

Now that you have your public and private key, the public key is named "id_rsa.pub" and the private key is named as id_rsa. Using these keys you can configure SSH. After ensuring your key-based authentication is working without any issues, go ahead and disable the password authentication mechanism. To do the same, open your ssh config file and scroll through the file until you see the line that starts with "Password Authentication yes". Now replace the line with "Password Authentication no" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

# To disable tunneled clear text passwords, change to no here!

Password Authentication no

Save and exit.

Note:

Now restart the service and do the test. As a precaution, I advise, keep the current session on, and do the test in the new terminal. Once you have verified with your SSH service, then close all the sessions.
Step 6: Disable X11 Forwarding

The X11 Forwarding option is enabled in many Linux distros by default. It is a mechanism that permits remote users to execute GUI (graphical) applications from their SSH sessions. It can be misused if things go to the wrong hands as ssh clients can easily generate fake cookies and transmit over the remote SSH server after they establish the connection. To prevent such kind of security gaps, it is better to disable X11Forwarding. To do this, just open your ssh config file and scroll through the file until you see the line starts with "X11Forwarding yes". Now replace the line as "X11Forwarding no" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10

Save and exit.

Note:

Now, restart the service and do the testing accordingly.
Step 7: Disable Empty Passwords

Linux system permits users to create with an empty password. It is highly recommended not to use an empty password on SSH servers as it creates some security issues like brute force attacks. Therefore, we are advised to disable the user with an "Empty Password" in SSH. To apply this, open your ssh config file and scroll through the file until you see the line that starts with "#PermitEmptyPasswords no". Uncomment/remove the (#) from the beginning of the line and keep the line as "PermitEmptyPasswords no" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

# To disable tunneled clear text passwords, change to no here!

PermitEmptyPasswords no

Save and restart the service.

Step 8: Set Max Authentication Attempts

It is good practice and recommended to protect our server against brute force attacks. If someone tries to access your server with incorrect passwords, more than a few attempts will be disconnected automatically. To enable this feature, open your ssh config file and scroll through the file until you see the line that starts with "#MaxAuthTries 6". Uncomment/remove the (#) from the beginning of the line and keep the line as "#MaxAuthTries 3" as highlighted below :

$ sudo vi /etc/ssh/sshd_config

 

MaxAuthTries 3

Save and exit.

Note:

Now restart the service. If you test using the wrong password more than 3 times you will receive a message like the following:
Received disconnect from 192.168.1.100 port 1875:3: Too many authentication failures
Disconnected from 192.168.1.100 port 1875
Step 9: Allow only Specific IP Address

By default, there is no restriction to accessing the SSH server from anywhere with any IP address. As part of the security concern, it is good practice and recommended to permit only a specific IP address. For example: If you have a corporate/business network with a static public IP address, then permit only those and deny the rest of the IP address. This can be done by adding the following entries into "/etc/hosts.allow" file.

$ sudo vi /etc/hosts.allow

 

sshd : 192.168.1.200 : ALLOW
sshd : 192.168.1.201 : ALLOW
sshd : ALL : DENY

Save and exit.

Note:

The above configuration will permit only two IP's "200 and 201" and deny all other IP addresses access to our SSH server.
Step 10: Set Idle Timeout

By default, there is no idle timeout set on Linux servers or clients, it is good practice to set up idle timeout sessions on the server itself, it will prevent unauthorized access to the system. For e.g., if a user walks away from his desk and doesn't lock the screen and is busy with something else, in the meantime someone can access the user's ssh session. To reduce this kind of risk, it is better to enable timeout value. The recommended setting is 300 seconds (5 minutes), you can set this based on your policy. Also set the ClientAliveCountMax is 0. Open your ssh config file and scroll through the file until you see the line that starts with "#ClientAliveInterval 0". Uncomment/remove the (#) from the beginning of the line and keep the line as "ClientAliveInterval 300" and set "ClientAliveCountMax is 0" as highlighted below:

$ sudo vi /etc/ssh/sshd_config

 

ClientAliveInterval 300

 

ClientAliveCountMax is 0

Save and exit.

Note:

Now restart the service. We have set up the idle timeout as 300 seconds, which is 5 minutes.
SSH warning banner

It is always good practice to create SSH warning banners and Welcome messages to prevent unauthorized entries to our server. You can display these warning messages in two forms: "before login" and "after login".

To create a Warning message before logging in you can use a common warning message file for SSH and it will be located in the "/etc/issue and /etc/issue.net" or we can create a custom file like "/etc/ssh/sshd_banner" and copy the banner path into the sshd_config file. The content will be displayed before the password prompts.

To create a Welcome message after login you can use the "/etc/motd" file. The content of the welcome message will be displayed after every successful ssh login.

$ sudo vi /etc/ssh/sshd_banner

ssh warning banner in linux

save and exit.

Note:

Now open "/etc/ssh/sshd_config" file and scroll through the file until you see the line starts with "#Banner none". Uncomment/remove the (#) from the beginning of the line and keep the line as "Banner /etc/ssh/sshd-banner" as highlighted below:

$ sudo vi /etc/ssh/sshd_config

 

Banner /etc/ssh/sshd-banner

save and exit.

Next, add the Welcome message after successfully logging in to the "/etc/motd" file".

$ sudo vi /etc/motd

ssh welcome banner after login

Note:

Finally, restart the service, do the test and see both Warning and Welcome messages.

 

$ sudo ssh john@192.168.1.100 -p 1875

Output:

ssh banner alert in linux

Conclusion

I hope this guide can help Linux users to understand how to install and secure the SSH server in Linux. If you know what and where to tweak, then hardening is much simpler than you think.

Thank you for taking the time to read! Drop me your feedback/comments. If you like this article, kindly share it and it may help others as well.

Thank you!

Support My Work

Thank you for your support and for being a part of my journey, I would be very grateful if you could consider buying me a coffee. The contributions you make will help me to continue to produce quality content and enhance my readers' experience.


Buy Me A Coffee

Thank you for your endless support!

 

Leave a Reply

Your email address will not be published.

L