When it comes to accessing remote devices such as servers, routers, and switches, SSH protocol comes highly recommended given its ability to encrypt traffic and ward off anyone who might try to eavesdrop on your connections.
Be that as it may, the default settings of SSH are not infallible and additional tweaks are needed to make the protocol more secure. In this guide, we explore different ways that you can use to secure and harden OpenSSH installation on the server.
1. Setup SSH Passwordless Authentication
By default, SSH requires users to provide their passwords when logging in. But here’s the thing: hackers can guess passwords or even perform a brute force attack using special hacking tools and gain access to your system. To be on the safe side, the use of SSH passwordless authentication is highly encouraged.
The first step is to generate an SSH key-pair which consists of a public key and a private key. The private key resides on your host system whilst the public key is then copied to the remote server.
Once the public key is successfully copied, you can now SSH in to the remote server seamlessly without having to provide a password.
The next step is to disable password authentication, To achieve this, you need to modify the SSH configuration file.
$ sudo vim /etc/ssh/sshd_config
Inside the configuration file, scroll and locate the following directive. Uncomment and change the option 'yes'
to 'no'
PasswordAuthentication no
Then restart the SSH daemon.
# sudo systemctl restart sshd
At this point, you will only have access to the remote server using the SSH key authentication.
2. Disable User SSH Passwordless Connection Requests
Another recommended way of fortifying the security of your server is to disable SSH logins from users without passwords. This sounds a bit strange but sometimes system administrators can create user accounts and forget to assign passwords – which is a very bad idea.
To reject requests from users without a password, again, head over to the configuration file at /etc/ssh/sshd_config
and ensure that you have the directive below:
PermitEmptyPasswords no
Then restart SSH service for the change to be effected.
$ sudo systemctl restart sshd
3. Disable SSH Root Logins
It’s a no brainer what can happen if a hacker manages to brute force your root password. Allowing remote root login is invariably a bad idea that could jeopardize your system’s security.
For this reason, it is always recommended that you disable SSH remote root login and instead stick to a regular non-root user. Once again, head over to the configuration file and modify this line as shown.
PermitRootLogin no
Once you are done, restart SSH service for the change to be effected.
$ sudo systemctl restart sshd
Henceforth, remote root login will be deactivated.
4. Use SSH Protocol 2
SSH comes in two versions: SSH protocol 1 and protocol 2. SSH protocol 2 was introduced in 2006 and is more secure than protocol 1 thanks to its strong cryptographic checks, bulk encryption and robust algorithms.
By default, SSH uses protocol 1. To change this to the more secure Protocol 2, add the line below to the configuration file:
Protocol 2
As always, restart SSH for the changes to come into effect.
$ sudo systemctl restart sshd
Going forward, SSH will use Protocol 2 by default.
To test if SSH protocol 1 is supported any more, run the command:
$ ssh -1 user@remote-IP
You will get an error that reads “SSH protocol v.1 is no longer supported”.
In this case, the command was:
$ ssh -1 [email protected]
Additionally, you can simply specify the -2
tag just to be sure that Protocol 2 is the default protocol in use.
$ ssh -2 [email protected]
5. Set SSH Connection Timeout Idle Value
Leaving your PC unattended for extended periods of time with an idle SSH connection can pose a security risk. Someone can simply pass by and take over your SSH session and do whatever they please. To address the issue, it’s prudent, therefore, to set an idle timeout limit which when exceeded, the SSH session will be closed.
Once again, open your SSH configuration file and locate the directive “ClientAliveInterval”. Assign a reasonable value, for example, I have set the limit to 180 seconds.
ClientAliveInterval 180
This implies that the SSH session will be dropped if no activity is registered after 3 minutes which is the equivalent of 180 seconds.
Then restart the SSH daemon to effect the changes made.
$ sudo systemctl restart sshd
6. Limit SSH Access to Certain Users
For an added security layer, you can define the users who require SSH protocol to log in and perform remote tasks on the system. This keeps off any other users who might try to gain entry to your system without your approval.
As always, open the configuration file and append the directive “AllowUsers” followed by the names of users you want to grant. In the example below, I have allowed the users ‘tecmint‘ and ‘james‘ to have remote access to the system via SSH. Any other user who tries to gain remote access will be blocked.
AllowUsers tecmint james
Thereafter restart SSH for the changes to persist.
$ sudo systemctl restart sshd
7. Configure a Limit for Password Attempts
Another way you can add a layer of security is by limiting the number of SSH login attempts such that after a number of failed attempts, the connection drops. So once again head over to the configuration file and locate the “MaxAuthTries” directive and define a value for the maximum number of attempts.
In this example, the limit has been set to 3 attempts as shown.
MaxAuthTries 3
And finally, restart SSH service as in the previous scenarios.
You might also find these following SSH related articles useful:
- How to Install OpenSSH 8.0 Server from Source in Linux
- How to Install Fail2Ban to Protect SSH on CentOS/RHEL 8
- How to Change SSH Port in Linux
- How to Create SSH Tunneling or Port Forwarding in Linux
- 4 Ways to Speed Up SSH Connections in Linux
- How to Find All Failed SSH login Attempts in Linux
- How to Disconnect Inactive or Idle SSH Connections in Linux
Conclusion
That was a roundup of some of the measures you can take to secure your SSH remote connections. It’s important to add that you should always assign strong passwords to users having remote access to thwart brute-force attacks. It’s our hope that you found this guide insightful. Your feedback is much welcome.
another tip: don’t use multiple years old version of security software, which normally has better defaults
I think there is one misunderstanding in alive intervals that I also had.
Simply setting some `ClientAliveInterval` setting to value for instance to 180 doesn’t mean connection will be dropped after not receiving a response in 180 seconds or 3 minutes.
Here comes in play another option `ClientAliveCountMax` which is by default set to 3 so actual drop time will be evaluated as the multiplication of both these values.
So in this example client will drop the connection, not after 3 minutes but 9.
The same applies to `ServerAliveInterval` and `ServerAliveCountMax`.
Beautiful.
Please post a tutorial on how to automate this process on multiple servers via ansible.
Cheers!
Are you sure SSH protocol 1 is default?
On my Debian 10 box (I know, it’s not Mint) the sshd manual says “The OpenSSH SSH daemon supports SSH protocol 2 only.”
Hey MrCalvin, For the avoidance of doubt, I have checked my Debian 10 VM and It reads ” The OpenSSH SSH client supports SSH protocol 2.” I didn’t see the “only” part at the end. Kindly check again and use the command
'ssh -1 user@host-IP'
to check if you can log in first before changing to Protocol 2.I get the error “SSH protocol v.1 is no longer supported” ;-)
So I guess you don’t have to bother about SSH protocol versions, at least on Debian 10/Buster
@MrCalvin,
Yes, in the latest version of SSH, the protocol v.1 is no longer supported, it comes with protocol 2 only…
Good to see all these SSH measures grouped in one place! I’ll bookmark this page :)
Thank you Toor, We’re glad you found the tutorial very useful. Keep it Tecmint for more!
Hi,
Thanks a lot
Very useful article
Thank you, Jalal for your feedback. I’m happy the tutorial was insightful.