7. [Optional] Preventing Dictionary Attacks

Note

This section is purely for your information; you are not expected to implement these protection measures, but it will be useful to you later on if you ever operate internet-facing SSH servers. These measures are also applicable to other services, not just SSH.

As you will rapidly come to realise when you have an internet facing (meaning able to accept connections from the internet) SSH server, there are many attempts of people trying to break into your system using known/harvested username/password pairs, or just trying to find weak passwords by brute force. Most of the time it just creates a lot of noise in the system, but sometimes they succeed, and then they have a vector into the rest of the network, and possibly an easier method to get root access to the system (if that was their goal, they may just want to enlist your server in their illicit activities.

Split access policy

For this reason, it can be quite useful to disable password authentication, and prefer to use authentication systems such as public-key authentication or other authentication systems such as one-time pads, where the password is different each time or calculated via some other parameter. However, to use public-keys, you need to able to put the key into the account. It also becomes more important to carry your encrypted private key (and usually also your public key) around with you when you travel, typically on a USB flash drive. In order to install your public key into your account, you either need to a) access the system locally and copy the key over, b) access another system that has the same home directory mounted, c) ask a system admininistrator to install it for you, or more likely d) authenticate via a password and install the key so you can subsequently authenticate using your public-key.

(d) above would be nice, but it does require that we are able to configure sshd to have a policy that allows password authentication to known client systems, and disables it for systems on the internet. Fortunately, recent versions of OpenSSH give us a way to do just that, using the Match keyword.

Let’s say for now that we only want to allow password authentication to IPv4 clients in 192.168.1.0/24, and public-key authentication can be used from anywhere. Phrased another way, be default we want password authentication to be disabled, and allow it explicitly.

Edit sshd_config, find, uncomment and disable the PasswordAuthentication option. Then, at the end of the file, add the following:

PasswordAuthentication no         Deny by defaultat end of file
Match Address 192.168.1.0/24      Effective until next Match block or End-of-File
     PasswordAuthentication yes

To test, we shall need to first ensure that the client won’t authenticate using public-keys (temporarily). We can do this by renaming ~/.ssh/authorized_keys on Server1 to something else, such as ~/.ssh/authorized_keys.OFF. That way, it will fall-back to trying a password.

Thus, according to our policy, only login via IPv4 should work. This is because public key authentication is the only allowable method for IPv6, and we’ve essentially broken that temporarily for our testing.

The easiest way in our particular case would be to force the use of IPv4 or IPv6 using the -4 or -6 option to ssh. Alternatively, we could specify the host as either server1.ipv4.localdomain or server1.ipv6.localdomain. Remember that typically, server1.localdomain will use the IPv6 address first.

When using such a policy, it becomes important to educate your users on the new policy, and provide resources for them to understand how to use the new authentication mechanism, and why this policy is in place to begin with.

Dynamic Banning

Another way to protect yourself is to scan your logs periodically (perhaps every 10 minutes), and dynamically ban — using hosts.deny or a firewall rule — any IPs where repeated authentication failures are happening, especially if the username that is being authenticated does not exist in the system. There are a number of products out there to assist with this. DenyHosts is one that scans the logs and edits hosts.deny, depending on particular rules that are set by the administrator. However, because an attacker might get lucky and successfully authenticate before being banned, DenyHosts supports a synchronised mode, whereby many participating servers tell a central repository which machines they have banned, so other systems can ban them also.