Linux – Harden SSH

SSH is one of the most widely used administration methods for Linux servers and it is because of that you will find seemingly endless amounts of devices accessible on the Internet that are listening on port 22 (default SSH port). As a direct result it is a widely targeted service when hackers attempt to gain access to your system. Unfortunately with all of the IOT devices out there that are notoriously guilty of leaving SSH running on defaults and folks not taking the time to harden their ssh server it is a recipe for disaster so in this post I will demonstrate how to harden the SSH service running on your Linux server to greatly reduce the number of hacking attempts on your machine and hopefully you will never see a breach at all.

One thing I would like to note is while each one of these methods take an important step in hardening your SSH server keep in mind security is built on layers and if you only implement 1 or 2 of these methods you will be at more risk than if you implemented them all. It is also important to remember that each of these steps reduces the ease of use of SSH to an extent as there are more criteria that you need to meet to make the connection so make sure that you come up with a work flow that will allow for the most security and not give you a headache every time you need to login to your server. I can personally say that any SSH server I have accessible from the Internet has all of these methods in place in some form or fashion and I can still log into them with a single command from any workstation.


The Obvious:

The most obvious way to harden your SSH server that is accessible on the Internet is to not publish the SSH service of your server on the Internet at all, thus preventing any attempts on your server from the Internet. This can easily be done by putting a firewall in front of your server and not port forwarding any ports to the SSH service of your server. I will not go into details on how to accomplish this as it is very environment specific and for this article I will assume that there is a specific requirement that mandates SSH is accessible from the public Internet.


Highly Effective and Easy:

From running several SSH servers on line for several years I have found that there are 2 simple steps that will bring the unauthorized login attempts on your server to almost zero and render many of the ones that do still get through useless.

Change the Port Number SSH Listens on:

The first step will be to change the port that SSH is listening (TCP: 22) on to a random high port that is not used on your server. After doing this you will see almost all of the unauthorized login attempts disappear as most of the attempts are run by scripts and are often not configured to take the time to scan obscure port numbers and probe them for the services they are running. To change the port number ssh is listening on edit the ssh configuration file;

nano /etc/ssh/sshd_config

and change the following line at the top of the file from


now save the file and reload the ssh service.

If you attempt to connect via ssh on port 22 you will be unable to connect and need to specify port 47000 manually and you will be able to login.

Disable SSH Login for Root

As I stated earlier the previous step will greatly reduce the number of attempts you see but you might still occasionally see unauthorized login attempts that are often attempts to login on the root account as every Linux machine has a root account making it an obvious target. The best plan of action is to disable the user root from logging on via ssh at all. To do that again you will need to edit the ssh configuration file;

nano /etc/ssh/sshd_config

and search for the line

Make sure it is uncommented and is set to ‘no’ like shown below, if it is not in the file at all just append it to the end.

Save the file and reload the ssh service.

At this point root will be unable to login via SSH, to test this as long as your root account is active you can attempt to login and it will never accept any password for root.


Define SSH Users

Another step you should take on any SSH server on the Internet is to only allow specific users or users who below to a specific group to authenticate via ssh. The most effective method is to use a group so then you don’t have to constantly go edit the SSH configuration file when you need to remove or add a user access to SSH. To only allow users that are a part of the group ‘ssh’ to login via ssh add the following line to the ssh configuration file.

Save and close the SSH configuration file and reload the SSH service.

Add any users that will need SSH access to that group with the following command.

sudo usermod: With root privileges run the usermod command.

-aG : Append the user to the following group.

ssh: Group to append the user to.

<username>: The username of the account you wish to grant SSH access to.

At this point any users that you will add to that group will be allowed to login via ssh. To test this add a new user to the group ssh and attempt to login to your system via ssh as them and compare that against when you attempt with that user when they are not a member of that group. One thing you will want to keep track of and prune periodically are the users who are in the allowed ssh group because it is no use to do this if you have 100 users on the server who 10 of which need SSH access and you have added all 100 users on the server to the SSH group, doing that only will add more setup work for you with no security gain.


Restrict SSH Access to a Single Host

Doing this may not be the most practical thing to do in some environments but if you restrict SSH to only a single host on the Internet such as a jump host or the external IP address of your gateway allowing your entire LAN access, then the only time you will see unauthorized login attempts is if your jump host server gets compromised or if you allowed your external IP address of your gateway, a host on your network would be compromised. That also has an added benefit because if you start to see weird login attempts coming from your jump host or your LAN you have more data to identify what is going on and stop some other sort of malicious activity.

There are 2 ways you can do this if you are running ip tables then adding these 2 rules into your INPUT chain will block all traffic to your SSH server and only allow the address or range you specified.

1st command:

sudo iptables -A INPUT: with root privileges in IPtables append a rule to the INPUT chain.

-p tcp: Specifies the protocol as TCP.

–dport <SSH PORT>: Specifies the destination port, if your ssh server is listening on port 47000 this section would be “–dport 47000”

–source <IP or IP RANGE>: Specifies the source address or subnet that the traffic will be coming from. To add a single host such as it would be “–source” and to add an entire subnet it would be “–source”

-j ACCEPT: Specifies the action to take when traffic meeting this criteria is met in this case it will accept the traffic


2nd command:

sudo iptables -A INPUT: with root privileges in IPtables append a rule to the INPUT chain.

-p tcp: Specifies the protocol as TCP.

–dport <SSH PORT> : Specifies the destination port, if your ssh server is listening on port 47000 this section would be “–dport 47000”

-j DROP: drops all traffic

One thing to note is because of the way IPtables processes the rules it is important you enter these commands in the order I have provided because if the order is inverted it will block the traffic before it sees that it is allowed later in the chain.

Lastly make sure you save your IPtables rules so they last through a reboot.


If you are not running IPtables or want another method to restrict access by IP address you can use TCP Wrappers. First you will need to block all SSH traffic by editing the following file.

Adding the following line to block all ssh traffic from all hosts.

Then edit the following file.

Adding the following line to allow all ssh traffic from a specific host

This will allow all IP addresses from the subnet to connect via ssh, to only allow a specific ip address it would be “<IPADDR>/32”

At this point after preforming 1 of the 2 ways I described above your server will only respond to ssh from addresses that you have explicitly specified.


Add Key Based Authentication

Key based authentication adds even more security to authorized users that are allowed to use SSH because not only will the attacker need the key file that corresponds to the user they are trying to authenticate with they will also need the password that the key file is encrypted with (assuming the key file was setup with a password). This is something that I personally believe every device that has SSH accessible on the Internet should have as an added security measure. I will not go into how to configure key based authentication in this post as I have already outlined it in previous posts, see the following post for instructions on how to configure key based authentication.

Configure Key Based Authentication


At this point if you have followed all the steps in this article and tested that they preform as expected you have seriously reduced your risk of having SSH accessible from the Internet and can sleep better at night. As I stated earlier security is built on layers so make sure you design a work flow that allows for the incorporation of all of these methods for the highest security!

I hope this article helps you harden your SSH server, if it helped please share on social media.

Leave a Comment