1. Overview

It is a known fact that Secure Shell (SSH) is an indispensable protocol for remote administration and secure communication on Linux and Unix-based systems. Hence, it’s obviously imperative to take extra precautions to harden the SSH server. Besides, securing the SSH server safeguards our system from malicious intruders and ensures the confidentiality and integrity of our data.

In this tutorial, we’ll understand the importance of SSH security and review the essential steps to toughen it in Linux.

2. Understanding the Need

To begin, let’s try to comprehend why this process is necessary. Basically, SSH servers provide an entry point to our system, which makes it a vulnerable target for attackers. In general, securing SSH servers can result in the following:

  • prevent unauthorized access to the server
  • mitigate brute force attacks
  • enhance data privacy between client and server
  • safeguard against vulnerabilities

Now that we understand its significance, let’s delve into the strategies to harden our SSH server effectively.

3. Keep SSH Updated

Nonetheless, ensuring that our SSH server software is up-to-date is the foundation of security. Very often, developers release updates and patches to address vulnerabilities and enhance security.

So, let’s learn to update SSH on Debian or Ubuntu:

$ sudo apt update
sudo apt upgrade

Likewise, we update SSH on CentOS or RHEL:

$ sudo yum update

Hence, regularly updating our SSH software guarantees protection against the latest threats. Also, we should regularly review the SSH security policies and update them if necessary. As security threats evolve, we need to adjust our configurations and access controls to maintain a high level of protection.

4. Disable Root Login

Alternatively, another important security practice is to disable direct root login via SSH. This is because logging in as root provides unrestricted access to the system, which is exploited by attackers.

To disable root login, we edit the SSH configuration file:

$ sudo nano /etc/ssh/sshd_config

Then, we locate the line that says PermitRootLogin and set it to no:

$ PermitRootLogin no

After making this change, we restart the SSH service:

$ sudo systemctl restart ssh

So instead of root login, we should create a separate user with administrative privileges and use sudo for tasks.

5. Implement Two-Factor Authentication (2FA)

Furthermore, we can boost SSH security by providing a form of authentication. So, we use tools such as Google Authenticator to set up 2FA for SSH.
The first step to enable 2FA is to install the Google Authenticator PAM module:

On Debian or Ubuntu:

$ sudo apt install libpam-google-authenticator

On CentOS or RHEL:

$ sudo yum install google-authenticator

Subsequently, we run the google-authenticator command as the user to configure 2FA, which generates backup codes and a QR code for scanning with the Google Authenticator application.

6. Configure SSH Port

By default, SSH connects with port 22, which often becomes the soft target for attackers. Hence, to hamper this, we changed the default port to add an extra layer of security and make it less predictable.

To do this, let’s first edit the SSH configuration file:

$ sudo nano /etc/ssh/sshd_config

Next, we identify the line that contains the port number. Then, we substitute it with a different port, preferably one outside the well-known range (1-1024). Let’s say we set it to 2222:

$ Port 2222

After making the change, we restart the SSH service:

$ sudo systemctl restart ssh

Nevertheless, we should always ensure the new port is open in our firewall configuration.

7. Enable Fail2ban

Additionally, another strategy for intrusion detection and prevention is to implement Fail2Ban, an intrusion prevention tool that scans log files and bans IPs showing malicious behaviour. Principally, it defends against brute force attacks.

To install Fail2Ban on Ubuntu or Debian, let’s run the command:

$ sudo apt update
$ sudo apt install fail2ban

Alternatively, we can install it on CentOS or RHEL:

$ sudo yum install fail2ban

Now that we’ve installed it, we create a new configuration file:

$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Then, we edit the jail.local file to customize the Fail2Ban settings to our needs. Further, we can configure it to monitor the SSH service and set up rules for banning IPs after a certain number of failed login attempts.

So, in this way, we can block IP addresses that make repeated unsuccessful login attempts.

8. Disable Password Authentication and Enable Public Key Authentication

Irrefutably, passwords play a significant role in SSH security. We need to ensure that the passwords are complex and not easily guessable. However, using SSH keys for authentication is a more secure approach owing to the fact that SSH keys are longer and harder to crack than passwords.

Hence, to further enhance security, especially from password-based brute force attacks, let’s consider disabling password authentication entirely and relying solely on SSH keys for authentication as the latter provide a two-factor authentication mechanism.

First, let’s edit the SSH configuration file:

$ sudo nano /etc/ssh/sshd_config

Then, let’s locate the line `PasswordAuthentication` and set it to `no`:

PasswordAuthentication no

After making this change, we restart the SSH service:

$ sudo systemctl restart ssh

Evidently, SSH key authentication is a more secure way to authenticate than password-based authentication. Now, let’s see another way to perform public key authentication and disable password authentication.
First, we configure the settings in the SSH configuration file (`/etc/ssh/sshd_config`):

PasswordAuthentication no
PubkeyAuthentication yes

As a result, this configuration disables the password-based authentication and enforces the use of public keys.

9. Regularly Monitor SSH Logs

In most cases, regularly monitoring our SSH logs to analyze login attempts and authentication failures can alert us to potential security threats.
Typically, tools such as grep and awk filter and analyze the log entries.

For instance, let’s check for failed login attempts in the SSH logs:

$ grep 'Failed password' /var/log/auth.log

Typically, the SSH logs are found in /var/log/auth.log on Debian or Ubuntu and /var/log/secure on CentOS or RHEL.

We should regularly review your SSH logs and take prompt action in the event of any intrusion attempts. This includes blocking IP addresses, changing SSH keys, or implementing additional security measures.

10. Limit SSH Access

In addition, we can also implement access controls to limit the user access to only the necessary services and resources. To achieve this, we use the /etc/ssh/sshd_config file to specify which users or groups are allowed or denied SSH access.

First, let’s learn how to allow only specific users:

AllowUsers user1 user2

Alternatively, we can also deny access to specific users or groups:

DenyUsers user3

We can also set the appropriate file permissions for SSH keys and configuration files. For example, we can use restrict access to the private key:

$ chmod 600 ~/.ssh/id_rsa
$ chmod 644 ~/.ssh/id_rsa.pub

Additionally, we can set file ownership to a specific user to prevent other users from reading or modifying the files. Another strategy is to use firewall rules to restrict SSH access to trusted IP addresses. For instance, we can use ufw on Ubuntu or firewalld on CentOS.

Let’s first see how to allow SSH access only from a specific IP address:

$ sudo ufw allow from  to any port 2222

Analogously, let’s see how to work on CentOS with firewalld:

$ sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="" port protocol="tcp" port="2222" accept'
$ sudo firewall-cmd --reload

Most certainly, this limits the attack surface and reduces the risk of unauthorized access.

11. Use SELinux or AppArmor

Security-Enhanced Linux (SELinux) and AppArmor are mandatory access control (MAC) systems that provide an extra layer of security by implementing fine-grained access controls on processes and resources. We can configure them to restrict the SSH server behaviour and reduce the attack surface.

To enable SELinux or AppArmor, we should consult the documentation for the specific Linux distribution, as configurations can vary.

12. Conclusion

In conclusion, hardening the SSH server in Linux is essential to maintain the system’s security and integrity. In this article, we discussed the numerous security strategies to reduce the risk of unauthorized access and security breaches.

Nonetheless, maintaining SSH security requires constant vigilance to protect our system from new and emerging attacks and weaknesses.

1 Comment
Inline Feedbacks
View all comments
Comments are closed on this article!