Brute Force SSH Protection

In this section, I want to cover how to protect against attempts to brute force your SSH server username/password combination, something that occurs frequently by automated bots.

The easiest way to help curb brute force attempts is to change the port it operates on which I covered in Part 3, but that still leaves the port open (albeit on a non-standard port), it doesn’t actually protect against brute force attacks.

In order to implement the protection, we will designate a few rules in iptables, which are tables provided by the Linux kernel firewall, and the chains and rules it stores. Throughout this post, I will refer to a couple items that may differ for your machine. It is worth checking these parts before you begin.

  • eth0     :this is the name of the active network interface. The easiest way to check this is to read the name of the active link from the command, ifconfig
  • 22     :this is the default port that SSH operates on. In Part 3, I suggest changing it. If you have and have forgotten the port number, you can read it on line 5 of the config file, /etc/ssh/sshd_config

Ok, on to the actual setup. If you simply add an iptables rule, i.e.

sudo iptables -A INPUT <some_rule_here>

it will be wiped after each reboot, which makes it useless at worst, and tedious at best. In order to make it stick, we will create two new files, one that is read when the network interface is brought online, the other when it is taken offline.

Lets make the first file that adds the rules when the interface comes online. Create the file and open it for editing:

sudo vi /etc/network/if-up.d/bruteforceprot

In this empty file, add the following entries (note that you should change eth0 and the default port number 22 to match the specific settings of your machine):

#!/bin/bash
[ "${METHOD}" != loopback ] || exit 0
/sbin/iptables -A INPUT -i _eth0_ -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
/sbin/iptables -A INPUT -i _eth0_ -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 --rttl --name SSH -j DROP

I will explain each of these parameters at the end of the article. In order for the bash script to be run, it need to be executable. You can accomplish that with the following command:

sudo chmod u+x /etc/network/if-up.d/bruteforceprot

Note that the command:

sudo chmod +x /path/to/some/file

will add the executable bit to the user/owner, group and world.

In order to ensure the rules aren’t added twice if the interface cycles, create a file that removes the rules when the interface goes offline. Create the file and open it for editing:

sudo vi /etc/network/if-down.d/bruteforceprot

In this empty file, add the following entries (note that you should change eth0 and the default port number 22 to match the specific settings of your machine):

#!/bin/bash
[ "${METHOD}" != loopback ] || exit 0
/sbin/iptables -D INPUT -i _eth0_ -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
/sbin/iptables -D INPUT -i _eth0_ -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 --rttl --name SSH -j DROP

Again, it needs to be executable:

sudo chmod u+x /etc/network/if-down.d/bruteforceprot

To test and ensure that the scripts are working, first flush the rules from iptables.

iptables -F

Then run the if-up.d script and check that the rules are indeed present in iptables:

/etc/network/if-up.d/bruteforceprot
iptables -L

If the rules are working, check that the removal script works:

/etc/network/if-down.d/bruteforceprot
iptables -L

If both work, you’re good to go! Now, after 6 incorrect attempts to login in a 60 second window, all subsequent connection attempts will be ignored. If either doesn’t work, carefully check each of the scripts to ensure everything was entered correctly.

As promised, here are the meanings of each of the portions of the rules you just added:

  • /sbin/iptables     # this is the location of the iptables utility
  • -A     # this adds a rule
  • -D     # this deletes a rule
  • -i     # this is the interface name (eth0 is the default first wired network interface
  • -p     # this is the protocol of the rule/packet to check
  • -dport     # this is the destination port number
  • -m state . . . –name SSH     # this checks the state of the new incoming packets through your firewall and specifies that the rule shall only apply to connections where the same packet comes through more than 6 times in 60 seconds
  • -j     # this is the “jump” option, which says what to do when the rule is met
Tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.

Protected by WP Anti Spam