Since 2005 there has been an immense increase in brute force SSH attacks and though Linux is pretty secure by default, it does not stop evil programs from indefinitely trying to login with different passwords. Without proper protection your server is a sitting duck waiting for a bot to guess the right combination and hit the jackpot. But with just 2 commands we can stop that.

Symptoms

Here's an example of the auth.log file. You can see that even as I'm writing this article bots are trying different account combinations to get into my server:

Jul 28 21:32:16 impala sshd[10855]: Illegal user office from 213.191.74.219
Jul 28 21:32:16 impala sshd[10855]: Failed password for illegal user office from 213.191.74.219 port 53033 ssh2
Jul 28 21:32:16 impala sshd[10857]: Illegal user samba from 213.191.74.219
Jul 28 21:32:16 impala sshd[10857]: Failed password for illegal user samba from 213.191.74.219 port 53712 ssh2
Jul 28 21:32:16 impala sshd[10859]: Illegal user tomcat from 213.191.74.219
Jul 28 21:32:16 impala sshd[10859]: Failed password for illegal user tomcat from 213.191.74.219 port 54393 ssh2
Jul 28 21:32:16 impala sshd[10861]: Illegal user webadmin from 213.191.74.219
Jul 28 21:32:16 impala sshd[10861]: Failed password for illegal user webadmin from 213.191.74.219 port 55099 ssh2

Do you see the rate at which this is happening? Nowadays' connection speeds allow for crackers to try an enormous amount of combinations every second! It's time to stop this before someone hits the jackpot and my server is compromised.

About iptables

Iptables is the standard Linux firewall and though I use Ubuntu, it should be installed by default on any modern distribution. But it doesn't do anything yet. It's just sitting there, so we need to teach it some rules to prevent brute force attacks.

There are tools available to do this for us like fail2ban. Though it's a great piece of software and certainly has it's advantages, in this article I'd like to stick with iptables because fail2ban parses log files to detect brute force attacks at a certain interval, whereas iptables works directly on the kernel level. Besides I don't think many people know about iptables' full capabilities, and it comes preinstalled!

Easy Setup - Just 2 Rules

Because iptables comes standard with every Linux distribution we'll skip right to setting up the specific firewall rules we need. In depth configuring of iptables takes a bit of understanding and is not within the scope of this article, but let's take a look at these two statements:

$ sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
$ sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP

The -i _eth0 is the network interface to which ssh connections are made. Typically this is eth0, but maybe you need to change it.

That's it! Together they will rate-limit all incoming SSH connections to 8 in a one minute window. Normal users will have no trouble logging in, but the brute force attacks will be dropped, limiting the number of possible account combinations from unlimited, to 8. That's awesome!

Failsafe

While you're still testing, you might want to add the following line to your crontab

*/10 * * * * /sbin/iptables -F

This will flush all the rules every 10 minutes, just in case you lock yourself out. When you're happy with the results of your work, remove the line from your crontab, and you're in business.

Advanced Setup - Want More?

Restore on Boot

You will find that on your next reboot, the rules are lost. Damn! You probably want these 2 brute force protection rules automatically restored, right? The most elegant way would probably be to restore the iptables rules when your network interface comes back online. Here how I would this on Ubuntu. Let's get the following content in a file: /etc/network/if-up.d/bfa_protection

#!/usr/bin/env 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 8 --rttl --name SSH -j DROP

Save the file and make it executable:

$ chmod a+x /etc/network/if-up.d/bfa_protection

Now every time your interface comes up, the rules are added to iptables. Sweet.

Remove on Shutdown

But to do this really clean, we need to have a script that removes the rules as well for when the interface goes down. Just to make sure the rules are never added twice. So let's also create a file: /etc/network/if-down.d/bfa_protection

#!/usr/bin/env 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 8 --rttl --name SSH -j DROP

-D removes a rule whereas -A adds one. Anyway. Let's save this file and make it executable:

$ chmod a+x /etc/network/if-down.d/bfa_protection

That's it! We're in business!

Like to Test It?

Very wise indeed, well iptables -L shows active rules so why not execute the following:

$ /etc/network/if-up.d/bfa_protection
$ iptables -L

Perfect. If you have another machine (not the one you're working on! you do not want to take the risk of getting banned yourself!) you could really test it by logging 8 times within 60 seconds. See if you get banned!

Now does the removal script work as well?

$ /etc/network/if-down.d/bfa_protection
$ iptables -L

Now the rules should be gone.

Undo

And oh yes, if at any time you run into problems, the following command will flush all the iptables rules:

$ iptables -F

And you can undo by just removing the files we created:

$ rm /etc/network/if-up.d/bfa_protection
$ rm /etc/network/if-down.d/bfa_protection
$ iptables -F # flush all the rules, just in case

More on Iptables

This is just one nice example of what you can do with the iptables firewall but there are many other uses for iptables in order to secure your system. There are scripts / wizards that will help you setup iptable rules like ksecure_firwall (a bash script by myself), or more widely used programs like fwbuilder or firestarter (both available through package managament like apt).

If you'd like to know more about iptables, this is a place to start, or you could just google of course.