Secure your Linux system’s SSH connection to protect your system and data. System administrators and home users alike need to harden and secure internet-facing computers, but SSH can be complicated. Here are ten easy quick-wins to help protect your SSH server.

Use SSH Protocol Version 2

In 2006, the SSH protocol was updated from version 1 to version 2. It was a significant upgrade. There were so many changes and improvements, especially around encryption and security, that version 2 is not backward compatible with version 1. To prevent connections from version 1 clients, you can stipulate that your computer will only accept connections from version 2 clients.

To do so, edit the /etc/ssh/sshd_config file. We’ll be doing this a lot throughout this article. Whenever you need to edit this file, this is the command to use:

sudo gedit /etc/ssh/sshd_config

Add the line:

Protocol 2

And save the file. We’re going to restart the SSH daemon process. Again, we’ll be doing this a lot throughout this article. This is the command to use in each case:

sudo systemctl restart sshd

Let’s check that our new setting is in force. We’ll hop over to a different machine and try to SSH onto our test machine. And we’ll use the -1 (protocol 1) option to force the ssh command to use protocol version 1.

ssh -1 [email protected]

Great, our connection request is rejected. Let’s ensure we can still connect with protocol 2. We’ll use the -2 (protocol 2) option to prove the fact.

ssh -2 [email protected] 

The fact that the SSH server is requesting our password is a positive indication that the connection has been made and you are interacting with the server. Actually, because modern SSH clients will default to using protocol 2, we don’t need to specify protocol 2 as long as our client is up to date.

ssh [email protected] 

And our connection is accepted. So it is only the weaker and less secure protocol 1 connections that are being rejected.

Avoid Port 22

Port 22 is the standard port for SSH connections. If you use a different port, it adds a little bit of security through obscurity to your system. Security through obscurity is never considered a true security measure, and I have railed against it in other articles. In fact, some of the smarter attack bots probe all open ports and determine which service they are carrying, rather than relying on a simple look-up list of ports and assuming they provide the usual services. But using a non-standard port can help with lowering the noise and bad traffic on port 22.

To configure a non-standard port, edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Remove the hash # from the start of the “Port” line and replace the “22” with the port number of your choice. We use port 479 for this example. Save your configuration file and restart the SSH daemon:

sudo systemctl restart sshd

Let’s see what effect that has had. Over on our other computer, we’ll use the ssh command to connect to our server. The ssh command defaults to using port 22:

ssh [email protected] 

Our connection is refused. Let’s try again and specify port 470, using the -p (port) option:

ssh -p 479 [email protected] 

Our connection is accepted.

Filter Connections Using TCP Wrappers

TCP Wrappers is an easy to understand access control list. It allows you to exclude and permit connections based on characteristics of the connection request, such as IP address or hostname. TCP wrappers should be used in conjunction with, and not instead of, a properly configured firewall.  In our specific scenario, we can tighten things up considerably by using TCP wrappers.

TCP wrappers was already installed on the Ubuntu 18.04 LTS machine used to research this article. It had to be installed on Manjaro 18.10 and Fedora 30.

To install on Fedora, use this command:

sudo yum install tcp_wrappers

To install on Manjaro, use this command:

sudo pacman -Syu tcp-wrappers

There are two files involved. One holds the allowed list, and the other holds the denied list. Edit the deny list using:

sudo gedit /etc/hosts.deny

This will open the gedit editor with the deny file loaded in it.

You need to add the line:

ALL : ALL

And save the file. That blocks all access that hasn’t been authorized. We now need to authorize the connections you wish to accept. To do that, you need to edit the allow file:

sudo gedit /etc/hosts.allow

This will open the gedit editor with the allow file loaded in it. Add this line at the bottom:

sshd : 192.168.4.23

We’ve added in the SSH daemon name, SSHD,  and the IP address of the computer we’re going to allow to make a connection. Save the file, and let’s see if the restrictions and permissions are in force.

First, we’ll try to connect from a computer that isn’t in the hosts.allow file:

The connection is refused.  We’ll now try to connect from the machine at IP address 192.168.4.23:

Our connection is accepted.

Our example here is a bit brutal—only a single computer can connect. TCP wrappers is quite versatile and more flexible than this. It supports hostnames, wildcards, and subnet masks to accept connections from ranges of IP addresses. You are encouraged to check out the man page.

Reject Connection Requests With No Passwords

Although it is a bad practice, a Linux system administrator can create a user account with no password. That means remote connection requests from that account will have no password to check against. Those connections will be accepted but unauthenticated.

The default settings for SSH accept connection requests without passwords.  We can change that very easily, and ensure all connections are authenticated.

We need to edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that reads with “#PermitEmptyPasswords no.” Remove the hash # from the start of the line and save the file. Restart the SSH daemon:

sudo systemctl restart sshd

Use SSH Keys Instead of Passwords

SSH keys provide a secure means of logging into an SSH server. Passwords can be guessed, cracked, or brute-forced. SSH keys are not open to such types of attack.

When you generate SSH keys, you create a pair of keys. One is the public key, and the other is the private key. The public key is installed on the servers you wish to connect to. The private key, as the name would suggest, is kept secure on your own computer.

SSH keys allow you to make connections without a password that are—counterintuitively—more secure than connections that use password authentication.

When you make a connection request, the remote computer uses its copy of your public key to create an encrypted message that is sent back to your computer. Because it was encrypted with your public key, your computer can unencrypt it with your private key.

Your computer then extracts some information from the message, notably the session ID, encrypts that, and sends it back to the server. If the server can decrypt it with its copy of your public key, and if the information inside the message matches what the server sent to you, your connection is confirmed to be coming from you.

Here, a connection is being made to the server at 192.168.4.11, by a user with SSH keys. Note that they are not prompted for a password.

ssh [email protected]

SSH keys merit an article all to themselves. Handily, we have one for you. Here’s how to create and install SSH keys.

Disable Password Authentication Altogether

Of course, the logical extension of using SSH keys is that if all remote users are forced to adopt them, you can turn off password authentication completely.

We need to edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that starts with “#PasswordAuthentication yes.” Remove the hash # from the start of the line, change the “yes” to “no”, and save the file. Restart the SSH daemon:

sudo systemctl restart sshd

Disable X11 Forwarding

X11 forwarding allows remote users to run graphical applications from your server over an SSH session. In the hands of a threat actor or malicious user, a GUI interface can make their malign purposes easier.

A standard mantra in cybersecurity is if you don’t have a bonafide reason to have it turned on, turn it off.  We’ll do so by editing your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that starts with “#X11Forwarding no.” Remove the hash # from the start of the line and save the file. Restart the SSH daemon:

sudo systemctl restart sshd

Set an Idle Timeout Value

If there is an established SSH connection to your computer, and there has been no activity on it for a period of time, it could pose a security risk. There is a chance that the user has left their desk and is busy elsewhere. Anyone else who passes by their desk can sit down and start using their computer and, via SSH, your computer.

It’s much safer to establish a timeout limit. The SSH connection will be dropped if the inactive period matches the time limit. Once more, we’ll edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that starts with “#ClientAliveInterval 0” Remove the hash # from the start of the line, change the digit 0 to your desired value. We’ve used 300 seconds, which is 5 minutes. Save the file, and restart the SSH daemon:

sudo systemctl restart sshd

Set a Limit For Password Attempts

Defining a limit on the number of authentication attempts can help thwart password guessing and brute-force attacks. After the designated number of authentication requests, the user will be disconnected from the SSH server. By default, there is no limit. But that is quickly remedied.

Again, we need edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that starts with “#MaxAuthTries 0”. Remove the hash # from the start of the line, change the digit 0 to your desired value. We’ve used 3 here. Save the file when you made your changes and restart the SSH daemon:

sudo systemctl restart sshd

We can test this by attempting to connect and deliberately entering an incorrect password.

Note that MaxAuthTries number seemed to be one more than the number of tries the user was permitted. After two bad attempts, our test user is disconnected. This was with MaxAuthTries set to three.

Disable Root Log Ins

It is bad practice to log in as root on your Linux computer. You should log in as a normal user and use sudo to perform actions that require root privileges. Even more so, you shouldn’t allow root to log into your SSH server. Only regular users should be allowed to connect. If they need to perform an administrative task, they should use sudo too. If you’re forced to allow a root user to log in, you can at least force them to use SSH keys.

For the final time, we’re going to have to edit your SSH configuration file:

sudo gedit /etc/ssh/sshd_config

Scroll through the file until you see the line that starts with “#PermitRootLogin prohibit-password” Remove the hash # from the start of the line.

  • If you want to prevent root from logging in at all, replace “prohibit-password” with “no”.
  • If you are going to allow root to log in but force them to use SSH keys, leave “prohibit-password” in place.

Save your changes and restart the SSH daemon:

sudo systemctl restart sshd
Was this answer helpful? 44126 Users Found This Useful (44127 Votes)