How to Secure SSH in Linux (SSH Hardening)
The Secure Shell (SSH) protocol is one of the essential tools for Linux system administrators. This tool allows you to manage Linux servers from the comfort of your office or even from the comfort of your home. After all, this method is much better than having to put on your jacket and go through security barriers to enter the cold server room. The word secure in Secure Shell means that everything you type or transmit is encrypted. This eliminates the possibility that someone could obtain sensitive data by connecting to your network through a sniffer.
At this point in your Linux career, you need to know how to use Secure Shell or SSH to log in remotely and transfer files remotely. What you may not know is that the default configuration of SSH is actually relatively insecure. In this chapter, we'll explore ways to boost the default configuration. We'll explore how to use stronger encryption algorithms than the default, how to set up passwordless authentication, and how to set up a prison for Secure File Transfer Protocol (SFTP) users. As an added bonus, we'll explore how to scan SSH servers for vulnerable configurations and how to share a remote directory via Secure Shell Filesystem (SSHFS).
In this chapter, we will explore the following topics:
- Ensure that SSH protocol version 1 is disabled
- Create and manage keys to log in without the need for a password
- Disable root user login
- Disable login with username and password
- Configuring Secure Shell with Strong Encryption Algorithms
- Setting Global Encryption Policies in RHEL 8/CentOS 8
- FIPS Mode in CentOS 8/Red Hat 8
- Configure more accurate logging
- Access Control with Whitelisting and TCP Wrappers
- Configuring automatic checkouts and security banners
- Various other security settings
- Configuring Different Settings for Different Hosts
- Configure different settings for different users and groups
- Scan an SSH server
- Setting up a chroot environment for SFTP users
- Setting up shared directories with SSHFS
- Remote connection from Windows desktops
So if you're ready, let's get started.
Ensure that SSH protocol version 1 is disabled
The SSH version 1 protocol, which is the original SSH protocol, has serious flaws and should never be used. This protocol is still available on most Linux distributions, but thankfully it's disabled by default. However, let's say you open your file and see this line:/etc/ssh/sshd_config
Protocol 1
Or you might see:
Protocol 1, 2
If you see this, you are facing a problem.
The MAN Help page for files in Ubuntu says that version 1 of the protocol is still available for use with older devices. However, if you still have devices with such versions, you should seriously consider upgrading them. As Linux distributions are updated, you'll see that the SSH protocol version 1 is gradually being completely removed, as was the case with Red Hat and CentOS version 7.4.sshd_config
Creating and Managing Keys for Passwordless Login
SSH is an excellent set of tools used to communicate with remote servers. You can use the SSH component to enter the command line of a device remotely, and you can also use it to transfer files securely. The default way to use any of these components is to use a person's normal Linux account username and password. So, logging into the remote device from my OpenSUSE device terminal would look something like this:scp
sftp
donnie@linux-0ro8:~> ssh donnie@192.168.0.8
donnie@192.168.0.8's password:
While it's true that usernames and passwords are transmitted cryptographically over the network, making it harder for attackers to penetrate, it's still not the most secure way to do so. The problem is that the attackers have access to automated tools that can carry out password brute-force attacks against an SSH server. Botnets, such as Hail Mary Cloud, perform continuous scans across the internet to find servers with SSH-enabled.
If a botnet detects that servers are allowing access to SSH via username and password, it initiates a brute-force password attack. Unfortunately, such attacks have been successful several times, especially when server operators allow the root user to log in via SSH.
This old article provides more information about the Hail Mary Cloud botnet: Article Link.
In the next section, we will look at two ways to help prevent these types of attacks:
- Enabling SSH Login via Public Key Exchange
- Disable root user login via SSH
Now let's create a few keys.
Creating an SSH Key Set for a User
Each user has the option to create their own set of private and public keys. It doesn't matter if the user's client device is running Linux, macOS, Cygwin on Windows, or Bash Shell for Windows. In all these cases, the process of doing the work is exactly the same.
Creating SSH keys for users
There are many different types of keys you can create, and RSA keys with a length of 2048 bits are usually used as the default. Until not so long, RSA keys with a length of 2048 bits were considered strong enough for the foreseeable future. But now, the most recent guidance from the U.S. National Institute of Standards and Technology (NIST) recommends using an RSA key with a minimum of 3072 bits or an elliptical curve digital signature algorithm (ECDSA) key with a minimum of 384 bits. (Sometimes these ECDSA keys are also known as P-384). The reason for this recommendation is that they want to prepare us for quantum computing, which would be so powerful that it would render any weaker cryptographic algorithm obsolete. Of course, quantum computing is not yet operational, and so far it seems like it's always something that will come ten years from now, no matter what year we're in. But even if we assume that we ignore the problem of quantum computing, we must acknowledge that our current non-quantum computers are still getting more and more powerful. So, it's still not a bad idea to start using stronger crypto standards.
To view the list of cryptographic algorithms recommended by NIST and the proposed key lengths, you can visit this link.
For these few demos, let's switch to an Ubuntu 18.04 client. To create an RSA key pair with a length of 3072 bits, simply enter the following command:
donnie@ubuntu1804-1:~$ ssh-keygen -t rsa -b 3072
Here, we'll use the option to specify if we want to generate an RSA key, and we'll use the option to determine the bit length. When you are asked to enter the location and name of the keys, I just hit Enter to select the default values. You can leave the private key without a passphrase, but this method is not recommended.-t
-b
Note that if you choose a different name for your key files, you'll need to enter the full path of the files to make everything work properly. For example, in my case, I have to specify the path of the donnie_rsa keys./home/donnie/.ssh/donnie_rsa
You will see your new keys in the .ssh directory:
donnie@ubuntu1804-1:~$ ls -l .ssh
total 8
-rw------- 1 donnie donnie 2546 Aug 28 15:23 id_rsa
-rw-r--r-- 1 donnie donnie 573 Aug 28 15:23 id_rsa.pub
donnie@ubuntu1804-1:~$
Here:
id_rsa
It's your private key.id_rsa.pub
is your public key.
As you can see, id_rsa has limited access(), which means that only you (the donnie user) can read and write it, which provides decent security. The public key (id_rsa.pub) is readable for others to easily use on other servers for SSH authentication.-rw-------
Note that if you have created the default 2048-bit keys, the names will be similar.
- id_rsa key is your private key, and only you can read and write it.
- id_rsa.pub key is your public key that should be readable to everyone.
For ECDSA keys, the default length is 256 bits. If you decide to use ECDSA instead of RSA, enter the following command to create a strong 384-bit key:
donnie@ubuntu1804-1:~$ ssh-keygen -t ecdsa -b 384
Either way, when you look at the .ssh directory, you'll see that the names of the ECDSA keys are different from the RSA keys:
donnie@ubuntu1804-1:~$ ls -l .ssh
total 8
-rw------- 1 donnie donnie 379 May 27 17:43 id_ecdsa
-rw-r--r-- 1 donnie donnie 225 May 27 17:43 id_ecdsa.pub
donnie@ubuntu1804-1:~$
The beauty of elliptic curve algorithms is that their seemingly short key lengths are just as safe as long RSA keys. Even the largest ECDSA keys require less computing power than RSA keys. The maximum key length you can use with ECDSA is 521 bits. (Yes, you read that right. 521 bits, not 524 bits.)
So you may ask, why not only use 521-bit keys? The main reason is that 521-bit keys are not recommended by NIST. The reason for this is the concern of padding attacks, which can allow attackers to crack your encryption and steal your data.
If you take a look at the MAN's guide page for, you'll notice that you can create an Ed25519-type key, sometimes referred to as the curve25519. This variant is not on the list of algorithms recommended by NIST, but there are a few reasons why some people prefer to use it.ssh-keygen
The first reason is that RSA and DSA can disclose private key data when creating signatures if the operating system's random number generator is in trouble. ED25519 does not require the generation of random numbers when creating signatures, so it is resistant to this problem. Additionally, Ed25519 is coded to be much less vulnerable to side-channel attacks. (Side-channel attacks occur when someone tries to exploit vulnerabilities in the underlying operating system instead of a cryptographic algorithm.)
The second reason why some people prefer Ed25519 is precisely because it is not on the NIST list. These people are people who, rightly or wrongly, do not trust the recommendations of government agencies.
A few years ago, earlier this century, there was a scandal about the Dual Elliptic Curve Deterministic Random Bit Generator (Dual_EC_DRBG). It was a random number generator that was to be designed for use in elliptical curve cryptography. The problem was that initially, some independent researchers found that the manufacturer had the capabilities to create back doors, which anyone who was aware of could import. Interestingly, the only people who should have known about this capability were those who worked for the U.S. National Security Agency (NSA). At the request of the NSA, NIST placed Dual_EC_DRBG on its list of recommended algorithms, and this situation continued until April 2014, when it was finally removed.
For more details, you can visit the following links:
To read more details about ED25519, you can visit the following link:
For Ed25519, there is only one key size, which is 256 bits. So, to create a curve25519 key, just use the following command:
donnie@ubuntu1804-1:~$ ssh-keygen -t ed25519
Here are the keys I've created:
donnie@ubuntu1804-1:~$ ls -l .ssh
total 8
-rw------- 1 donnie donnie 464 May 27 20:11 id_ed25519
-rw-r--r-- 1 donnie donnie 101 May 27 20:11 id_ed25519.pub
donnie@ubuntu1804-1:~$
However, ED25519 has some potential disadvantages:
1. Lack of support by legacy SSH clients: However, this issue shouldn't be an issue when everyone on the team is using new operating systems and up-to-date SSH clients.
2. Only one fixed key length: This key is equivalent to 256-bit elliptic curve or 3,000-bit RSA encryption algorithms. So it may not be as good for foresight as some of the other algorithms we've covered.
3. Non-compliance with NIST requirements: If your organization must comply with NIST recommendations, you will not be able to use this key.
Finally, another type of key that can still be generated by ssh-keygen is the old DSA key. But it is not recommended to use this type. The DSA algorithm is outdated, fragile, and highly insecure by modern standards. So, when you get to the DSA, just say no.
Transferring the public key to the remote server allows the server to identify both me and my client's device. Before I can transfer my public key to the remote server, I must first add the private key to my session keyring. This requires two instructions. (One command runs ssh-agent, and the other adds the private key to the keyring):
donnie@ubuntu1804-1:~$ exec /usr/bin/ssh-agent $SHELL
donnie@ubuntu1804-1:~$ ssh-add
Enter passphrase for /home/donnie/.ssh/id_rsa:
Identity added: /home/donnie/.ssh/id_rsa (/home/donnie/.ssh/id_rsa)
Identity added: /home/donnie/.ssh/id_ecdsa (/home/donnie/.ssh/id_ecdsa)
Identity added: /home/donnie/.ssh/id_ed25519 (donnie@ubuntu1804-1)
donnie@ubuntu1804-1:~$
Finally, I can move my public keys to the CentOS server, which is located at 192.168.0.8:
donnie@ubuntu1804-1:~$ ssh-copy-id donnie@192.168.0.8
The authenticity of host '192.168.0.8 (192.168.0.8)' can't be established.
ECDSA key fingerprint is
SHA256:jUVyJDJl2AHJgyrqLudOWx4YUtbUxD88tv5oKeFtfXk.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to
filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 3 key(s) remain to be installed -- if you are
prompted now it is to install the new keys
donnie@192.168.0.8's password:
Number of key(s) added: 3
Now try logging into the machine, with: "ssh 'donnie@192.168.0.8'"
and check to make sure that only the key(s) you wanted were added.
donnie@ubuntu1804-1:~$
With this, your public keys have been added to the destination server, and you can log in to the server securely. Usually, you only make a pair of keys of the type you have chosen. As you can see here, I've made three pairs of keys, one pair of each type. All three private keys have been added to my session keyring, and all three public keys have been moved to the remote server. The next time I log in, I'll use Key Exchange and won't need to enter a password:
donnie@ubuntu1804-1:~$ ssh donnie@192.168.0.8
Last login: Wed Aug 28 13:43:50 2019 from 192.168.0.225
[donnie@localhost ~]$
As I said earlier, usually you only make one pair of keys for each device. However, there are exceptions to this rule. Some administrators prefer to use a different key pair for each server they manage, rather than using the same key pair for all servers. A convenient way to do this is to construct keys with file names that match the hostnames of the respective servers. You can then use the -i option to specify the key pair you want to use.
In this example, I only have one server, but I have different keys for it. Suppose I prefer to use the Ed25519 keys:
donnie@ubuntu1804-1:~$ ssh -i ~/.ssh/id_ed25519 donnie@192.168.0.8
Last login: Wed Aug 28 15:58:26 2019 from 192.168.0.3
[donnie@localhost ~]$
Now, you may be asking, if I log in without entering a password, how is it secure? The answer is that when I close the terminal window of my client device that I used to log in, the private key will be removed from my session keyring. When I open a new terminal and want to log in to the remote server, I see this message:
donnie@ubuntu1804-1:~$ ssh donnie@192.168.0.8
Enter passphrase for key '/home/donnie/.ssh/id_rsa':
Last login: Wed Aug 28 16:00:33 2019 from 192.168.0.3
[donnie@localhost ~]$
So every time I log in to this server, I have to enter my private key password (unless I add it back to the session keyring with the two commands I showed earlier)...