The Best Ways to Secure Your SSH Server

A stylized SSH prompt in a terminal window on a laptop.Eny Setiyowati / Shutterstock.com

Secure the SSH connection of your Linux system to protect your system and your data. System administrators and home users need to strengthen and secure computers connected to the Internet, but SSH can be complicated. Here are ten easy steps to take to protect your SSH server.

The basics of SSH security

SSH means Protective envelope. The name "SSH" is used interchangeably to refer to either the SSH protocol itself or the software tools that allow system administrators and users to establish secure connections to remote computers using this protocol.

The SSH protocol is an encrypted protocol designed to establish a secure connection over an unsecured network, such as the Internet. SSH on Linux is built on a portable version of OpenSSH project. It is implemented in a classic client-server model, with an SSH server accepting SSH client connections. The client is used to connect to the server and to view the session to the remote user. The server accepts the connection and runs the session.

In its default configuration, an SSH server listens for incoming connections on the transmission control protocol (TCP) port 22. Since it is a standard, well-known port, it's a target for actors of the threat and malicious robots.

Threat actors launch robots that scan a range of IP addresses for open ports. The ports are then queried to see if there are exploitable vulnerabilities. To think, "I am safe, there are bigger and better targets than the targets to target," is false reasoning. Robots do not select goals based on their merits; they systematically search for systems that they can violate.

You declare yourself a victim if you have not secured your system.

Safety friction

Safety frictions are the irritation, to whatever degree, that users and others will feel when applying security measures. We have long memories and we remember introducing new users to a computer system and hearing them ask for a horrified voice when they really needed to enter a password whenever and # They were connecting to the central computer. It was a safety friction for them.

(Incidentally, the invention of the password is credited to Fernando J. Corbató, another figure in the pantheon of computer scientists whose combined work contributed to the circumstances that led to the birth of Unix.)

The introduction of safety measures usually involves some form of friction for someone. Business owners must pay for it. Computer users may have to change their usual practices, remember another set of authentication details, or add additional steps to successfully establish a connection. System administrators will need to perform additional tasks to implement and manage the new security measures.

Securing and locking a Linux or Unix operating system can get involved very quickly. Here we present a set of easy-to-implement steps that will improve the security of your computer without the need for third-party applications and without ransacking your firewall.

These steps are not the last word in SSH security, but they will move you far beyond the default settings and without much friction.

Use the SSH version 2 protocol

In 2006, the SSH protocol was updated from version 1 to version 2. This was an important upgrade. There have been so many changes and improvements, especially with regard to encryption and security, that version 2 is not backward compatible with version 1. To prevent client connections from versioning 1, you can specify that your computer only accepts client connections from version 2.

To do this, edit the file / etc / ssh / sshd_config. We will do this often throughout this article. Whenever you need to edit this file, here is the command to use:

sudo gedit / etc / ssh / sshd_config

sudo gedit / etc / ssh / sshd_config in a terminal window

Add the line:

Protocol 2

sshd_config in gedit with highlighted changes

And save the file. We will restart the SSH daemon process. Again, we will do it a lot throughout this article. Here is the command to use in each case:

sudo systemctl restart sshd

sudo gedit / etc / ssh / sshd_config in a terminal window

Let's check that our new setting is in effect. We will switch to a different machine and try SSH on our test machine. And we will use the -1 (protocol 1) option to force the ssh command to use version 1 of the protocol.

ssh -1 dave@howtogeek.local

ssh -1 dave@howtogeek.local in a terminal window

Great, our connection request is rejected. Let's make sure we can always connect with protocol 2. We will use option -2 (protocol 2) to prove the fact.

ssh -2 dave@howtogeek.local

ssh -2 dave & # 39; howtogeek.local in a terminal window

The fact that the SSH server requests our password is a positive indication that the connection has been established and that you are interacting with the server. In fact, since modern SSH clients will default to protocol 2, we do not need to specify protocol 2 as long as our client is up to date.

ssh dave@howtogeek.local

ssh dave@howtogeek.local in a terminal window

And our connection is accepted. Thus, only the weaker and less secure protocol connections 1 are rejected.

Avoid port 22

Port 22 is the standard port for SSH connections. If you use a different port, it adds a little security to your system due to the darkness. Safety in the dark is never considered a real safety measure, which I have criticized in other articles. In fact, some of the smarter attack robots scan all open ports and determine the service they are carrying, instead of relying on a simple list of ports and assuming they provide the usual services. But using a non-standard port can help reduce noise and traffic on port 22.

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

sudo gedit / etc / ssh / sshd_config

SSH Configuration File in gedit with Highlighted Changes

Delete the hash number at the beginning of the "Port" line and replace the "22" with the port number of your choice. Save your configuration file and restart the SSH daemon:

sudo systemctl restart sshd

Let's see what effect it had. On our other computer, we will use the ssh command to connect to our server. The ssh command defaults to port 22:

ssh dave@howtogeek.local

ssh dave@howtogeek.local in a terminal window

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

ssh -p 479 dave@howtogeek.local

ssh -p 479 dave@howtogeek.local in a terminal window

Our connection is accepted.

Filter connections using TCP wrappers

TCP Wrappers is easy to understand access control list. It allows you to exclude and allow connections based on the characteristics of the connection request, such as the IP address or the host name. TCP wrappers should be used with and not in place of a properly configured firewall. In our specific scenario, we can dramatically improve things by using TCP wrappers.

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

To install on Fedora, use this command:

sudo yum install tcp_wrappers

sudo yum installs tcp_wrappers in a terminal window

To install on Manjaro, use this command:

sudo pacman -Syu tcp-wrappers

sudo pacman -Syu tcp-wrappers in a terminal window

There are two files involved. One contains the authorized list and the other, the refused list. Edit the refusal list with the help of:

sudo gedit /etc/hosts.deny

sudo gedit /etc/hosts.deny in a terminal window

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

hosts.deny file loaded in gedit

You must add the line:

ALL: ALL

And save the file. This blocks all unauthorized access. We must now allow the connections you want to accept. To do this, you must edit the authorize file:

sudo gedit /etc/hosts.allow

sudo gedit /etc/hosts.allow in a terminal window

This will open the gedit editor with the authorized file loaded.

hosts.allow file loaded in gedit with the highlighted changes

We added the name of the SSH daemon, SSHD, as well as the IP address of the computer on which we will allow the establishment of a connection. Save the file and see if the restrictions and permissions are in effect.

First, we will try to connect from a computer not in the hosts.allow file:

SSH connection denied by TCP wrappers "width =" 576 "height =" 97 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this); "onerror = this" onerror = this; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

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

SSH connection allowed by TCP wrappers

Our connection is accepted.

Our example here is a bit brutal: only one computer can connect. TCP wrappers are quite versatile and flexible enough. It supports host names, wildcard characters, and subnet masks accept connections from IP address ranges. You are encouraged to see the manual page.

Reject login requests without a password

Although this is a bad practice, a Linux system administrator can create a user account without a password. This means that remote login requests from this account will have no password to check. These connections will be accepted but not authenticated.

The SSH defaults accept login requests without a password. We can change this very easily and make sure that all connections are authenticated.

We need to modify your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

SSH configuration file loaded in gedit with highlgihted editions "width =" 646 "height =" 267 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this); "this on .onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until you see the line that reads with "#PermitEmptyPasswords no". Delete the hash # from the beginning 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 way to connect to an SSH server. Passwords can be guessed, cracked or forced brute. SSH keys are not open to this type of attack.

When you generate SSH keys, you create a key pair. One is the public key and the other is the private key. The public key is installed on the servers to which you want to connect. As its name indicates, the private key is secured on your own computer.

SSH keys allow you to establish password-free connections that are – counter-intuitively – more secure than connections using 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. Since it has been encrypted with your public key, your computer can decrypt it with your private key.

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

Here, a connection is established on the server at the address 192.168.4.11, by a user with SSH keys. Note that they are not asked to enter a password.

ssh dave@192.168.4.11

SSH request authenticated by SSH key in a terminal window "width =" 646 "height =" 367 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

SSH keys deserve an article on their own. We have one for you. here is how to create and install SSH keys.

RELATED, RELATED, RELATED: How to create and install SSH keys from the Linux shell

Disable password authentication completely

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

We need to modify your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

The publisher gedit with the ssh configuration file loaded and edits highlighted "width =" 646 "height =" 217 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this ); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until the line beginning with "#PasswordAuthentication yes" appears. Delete the # hash from the beginning of the line, replace the "yes" with "no", and save the file. Restart the SSH daemon:

sudo systemctl restart sshd

Disable X11 transfer

X11 forwarding allows remote users to run graphical applications from your server through an SSH session. In the hands of a threatening actor or a malicious user, a GUI can make their job easier.

If you have no good reason to activate it, disable it. We will do this by modifying your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

The publisher gedit with the ssh configuration file loaded and edits highlighted "width =" 646 "height =" 227 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this ); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until the line starting with "# X11Forwarding no" appears. Delete the # sign from the beginning 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 with your computer and no activity has been active for some time, this could pose a security risk. It is possible that the user has left his office and is busy elsewhere. Anyone who passes near his desk can sit down and start using his computer and, via SSH, your computer.

It is much safer to set a timeout limit. The SSH connection will be dropped if the idle period is the time limit. Once again, we will edit your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

The publisher gedit with the SSH configuration file loaded and edits highlighted "width =" 646 "height =" 277 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this ); "onerror" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until the line starting with "#ClientAliveInterval 0" appears. Delete the pound sign at the beginning of the line, change the number 0 to get the desired value. We 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

Setting a limit on the number of authentication attempts can help counteract password attacks 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 this is quickly resolved.

Again, we need to modify your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

The publisher gedit with the ssh configuration file loaded and edits highlighted "width =" 646 "height =" 252 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this ); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until the line starting with "#MaxAuthTries 0" appears. Delete the hash number at the beginning of the line, change the number 0 to the desired value. We used 3 here. Save the file when you have made your changes and restart the SSH daemon:

sudo systemctl restart sshd

We can test this by trying to log in and deliberately entering an incorrect password.

User is disconnecting after two bad authentication certificates in a terminal window "width =" 646 "height =" 147 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Note that the number of MaxAuthTries seemed to be one more than the number of tests allowed by the user. After two unsuccessful attempts, our test user is disconnected. That was with MaxAuthTries set to three.

Disable root connections

It is not recommended to log in as root on your Linux computer. You must log in as a normal user and use sudo to perform actions that require root privileges. Moreover, you should not allow root to connect to your SSH server. Only regular users should be allowed to connect. If they have to perform an administrative task, they must also use sudo. If you have to allow a root user to log in, you can at least force it to use SSH keys.

For the last time, we will have to edit your SSH configuration file:

sudo gedit / etc / ssh / sshd_config

The publisher gedit with the ssh configuration file loaded and edits highlighted "width =" 646 "height =" 232 "src =" / pagespeed_static / 1.JiBnMqyl6S.gif "onload =" pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this ); "onerror =" this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);

Scroll down the file until the line beginning with "#PermitRootLogin prohibit-password" appears on the screen. Delete the hash # from the beginning of the line.

If you want to prevent root login, replace "prohibit-password" with "no".
If you allow root to log in but you force them to use SSH keys, leave "prohibit-password" instead.

Save your changes and restart the SSH daemon:

sudo systemctl restart sshd

The ultimate step

Of course, if you do not need to run SSH on your computer at all, make sure it is disabled.

sudo systemctl stop sshd
sudo systemctl disable sshd

If you do not open the window, no one can access it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.