The Best Ways to Secure Your SSH Server
|Secure your Linux system7;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.
SSH Security Basics
SSH stands for Secure Shell. The name ;SSH; is used interchangeably to mean either the SSH protocol itself or the software tools that allow system administrators and users to make secure connections to remote computers using that protocol.
The SSH protocol is an encrypted protocol designed to give a secure connection over an insecure network, such as the internet. SSH in Linux is built on a portable version of the OpenSSH project. It is implemented in a classic client-server model, with an SSH server accepting connections from SSH clients. The client is used to connect to the server and to display the session to the remote user. The server accepts the connection and executes the session.
In its default configuration, an SSH server will listen for incoming connections on Transmission Control Protocol (TCP) port 22. Because this is a standardized, well-known port, it is a target for threat actors and malicious bots.
Threat actors launch bots that scan a range of IP addresses looking for open ports. The ports are then probed to see if there are vulnerabilities that can be exploited. Thinking, ;I7;m safe, there are bigger and better targets than me for the bad guys to aim at,; is false reasoning. The bots aren7;t selecting targets based on any merit; they7;re methodically looking for systems they can breach.
You nominate yourself as a victim if you haven7;t secured your system.
Security Friction
Security friction is the irritation2;of whatever degree2;that users and others will experience when you implement security measures. We7;ve got long memories and can remember introducing new users to a computer system, and hearing them ask in a horrified voice whether they really had to enter a password every time they logged in to the mainframe. That2;to them2;was security friction.
(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.)
Introducing security measures usually involves some form of friction for someone. Business owners have to pay for it. The computer users may have to change their familiar practices, or remember another set of authentication details, or add extra steps to connect successfully. The system administrators will have additional work to do to implement and maintain the new security measures.
Hardening and locking down a Linux or Unix-like operating system can get very involved, very quickly. What we7;re presenting here is a set of easy to implement steps that will improve the security of your computer without the need for third-party applications and without digging through your firewall.
These steps aren7;t the final word in SSH security, but they7;ll move you a long way forward from the default settings, and without too much friction.
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. We7;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. We7;re going to restart the SSH daemon process. Again, we7;ll be doing this a lot throughout this article. This is the command to use in each case:
sudo systemctl restart sshd
Let7;s check that our new setting is in force. We7;ll hop over to a different machine and try to SSH onto our test machine. And we7;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. Let7;s ensure we can still connect with protocol 2. We7;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 don7;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. Save your configuration file and restart the SSH daemon:
sudo systemctl restart sshd
Let7;s see what effect that has had. Over on our other computer, we7;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. Let7;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 hasn7;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.
We7;ve added in the SSH daemon name, SSHD
, and the IP address of the computer we7;re going to allow to make a connection. Save the file, and let7;s see if the restrictions and permissions are in force.
First, we7;ll try to connect from a computer that isn7;t in the hosts.allow
file:
The connection is refused. We7;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 brutal2;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 are2;counterintuitively2;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. Here7;s how to create and install SSH keys.