» Block brute force attacks with iptables
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
#!/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 8 --rttl --name SSH -j DROP
Save the file and make it executable:
chmod u+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
#!/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 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 u+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
And now there should be something like this in your terminal:

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.
Like this article?
|
Then Digg it! Or use another bookmark button below to show your support & help me spread the word. |
Hot StuffFlaming articles» Survive heavy traffic with you... | RelatedArticles like this one» Make SSH connections with PHP |
tags: ubuntu, security, linux, iptables, firewall, ssh
category: How to - Security
read: 63,863 times






tagcloud
#63. rob on 28 June 2008
Also, like someone said early on, just change ports and that will block the millions of script kiddie, I think I'm a hacker cuz I downloaded this program and can type in IP addresses people. Also think about what your server is used for people. If you resolve that dang log file, where do nearly ALL of the IPs fall? APNIC... Fucking ASIA... Just put IP blackholes for all of fucking China and Korea and be done with it already. I used to have 800+ attacks on my box per day, then I woke up and was like, gee, this webserver is only meant to serve people on campus here in texas... WTF do I need to have it available to the world for? So I blackholed china and korea, most of it at least, about a dozen entries, 202.0.0.1/8 and so on... And the attacks miraculously, stopped.
If you're not feeling like typing install some IDS software or better yet have someone who understands networking install a freakin' ASA or something on your network.
... [more]
Bottom line, if you don't know what you're doing learn. Don't just cut and paste shit off a website and expect to be secure.
ok I'm done.
~R
#62. makkksimal on 18 June 2008
And as always there a many ways to get what you like and need :)
#61. Kevin on 18 June 2008
#60. makkksimal on 17 June 2008
i think it is build in in ubuntu/debian
for further information tortoure you man pages
... [more]
man iptables-save
man iptables-restore
#59. Kevin on 31 May 2008
#58. Simon on 31 May 2008
#57. Chris on 10 May 2008
#56. Melvin on 28 November 2007
Very useful, thanks!
#55. Michael on 28 November 2007
I tried to install a port 22 throttle into my Iptables once before but the example lines didn't work. Yours worked just fine. One change I did make, though was to change the DROP to a REJECT --reject-with tcp-reset
(Those folks who run those bots annoy me! <G>)
... [more]
Thanks again!
P.S. Oh, and one thing I've never been able to get to work on my FC system (for two distros now) is for my own Iptables to "take" on startup. I can get on the Net, but my intranet machines can't until I drop the firewall (flush all the chains, etc.) and the restart it. This, even though I have "service iptables save" as the last line in my script, so that the chains are saved into the file FC reads on startup.
Thanks again!
#54. Kevin on 19 October 2007
But I think more elegant that the rules become active when networking comes up, and clear when it goes down.
There must be a Red Hat equivalent for the /etc/network/if-up.d method, but I just don't know Red Hat (clones) that well. So maybe you'd better ask them or their communities how to do it.
#53. Carl on 14 October 2007
And I see I'm not the only one (there are some others asking the exact same thing in the comments, yet nobody responded..).
#52. Andrew on 04 October 2007
#51. Kevin on 23 September 2007
#50. Pete on 22 September 2007
Maybe I'm just nit-picking though, because apart from that it's a really well-written and informative article
#49. erth64net on 20 September 2007
#48. Mukund on 12 September 2007
#47. Nphyx on 07 September 2007
The issue isn't of whether they're going to break in really. It's the amount of bandwidth (1gb/day for me for the last 3 days here) and the size of the logs (about 1mb per day). Not only does that add up fast, it makes it nearly impossible to check the logs to see what legitimate users are doing. As amusing as it is to watch 8 synchronized bots chew through a dictionary of passwords each day on every common user name starting with "Administrator" I only need a couple entries to send off a nastygram to their ISPs :)
#46. Nphyx on 07 September 2007
#45. Chiron on 21 August 2007
#44. math on 11 August 2007
Imagine if you used 8 char passwords instead! (now we're looking at 2.2 million years.)
This all assumes you arent noticing 100 attacks per second (!). Thats nearly a dos attack at that rate, and serious neglect of managing the huge log files that would result. (200 chars per attempt there. at 100 attempts/s * 200 chars we're looking at 20K/SECOND, or nearly 2 GIGS a day.
... [more]
So.
I think its better to put your effort into securing things that are really hackable, like that php script you wrote that no one else on the planet is using (thus you arent benefitting from 10,000 eyes on your code). Not to mention just plain not using a windows box to login to your unix servers, ever, cuz then they have your root password.
#43. Digerati on 10 August 2007
which is loaded with several scripts.
Not sure what to do.
#42. Kevin on 06 August 2007
#41. Daniel on 06 August 2007
Great article. Just one question.
The two rules are protecting us from "out side", but if the attack come from the internal network What do we need change in the rules ?
... [more] Bests
#40. Zigzo ZLinks on 05 August 2007
#39. Kevin on 03 August 2007
#38. Geog on 02 August 2007
I do this with -m limit. I haven't thought
about -m recent.
#37. Kevin on 02 August 2007
#36. Jay Fude on 02 August 2007
#35. Anon on 02 August 2007
The trouble with 8 per minute is that there is still a very small chance that one of those 8 tries hits your userid/password combo. At which point the attacker has your machine, even with your iptables rules.
#34. Thomas Mathiesen on 02 August 2007
#33. dany on 02 August 2007
http://www.hexten.net/wiki/index.php/Pam_abl
#32. psychicist on 02 August 2007
A brute force attack on such a configuration might be possible but requires some really heavy-duty supercomputer. If you upgrade to newer OpenSSH versions and encryption strengths there is not much to be broken into.
#31. Peter N. M. Hansteen on 02 August 2007
#30. Erm on 01 August 2007
tail -f /var/log/syslog/var/log/syslog
What's really fun is to do a whois on the ip that's doing the brute force attack, call their isp, and tell them one of their ips is doing a dictionary attack on your ssh server. Then if you hear a gulp ... you can tell THEY were the ones doing it. Classic.
... [more]
Personally I like denyhosts because you can set it up to contact their database, and get even more protection against attackers. I like the thought of being able to access my computer from anywhere in the world.
#29. Vinas on 31 July 2007
#! /bin/sh
# rate-limit connections to sshd
iptables -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --set
... [more] iptables -A INPUT -p tcp --dport 22 --syn -m recent --name sshattack --rcheck --seconds 300 --hitcount 3 -j LOG --log-prefix 'SSH REJECT: '
iptables -A INPUT -p tcp --dport 22 --syn -m recent --name sshattack --rcheck --seconds 300 --hitcount 3 -j REJECT --reject-with tcp-reset
#28. linuxtraveler on 31 July 2007
I didn't know this module!
#27. Asktheadmin on 31 July 2007
#26. kentborg on 31 July 2007
I would recommend against a non-standard port. It will confuse good users, it won't stop the bad guys, and it might make you complacent about maintaining your machine *and* having good passwords that are not reused elsewhere on the net.
-kb
#25. foutrelis on 31 July 2007
What should I do? What rules does it need? :P
Thanks in advance and keep up the great work! :)
#24. Lean Fuglsang on 31 July 2007
I mean, it is possible that a bruceforce attack will make it impossible for all IP adresses to login?
#23. Zotter on 31 July 2007
If you'd like to be preemptive and lock out known attackers even before they start on your box - try Denyhosts and use the shared database options.
http://denyhosts.sourceforge.net
... [more]
Think along the lines of a DNSRBL for ssh brute forcers. But one where the attackers pretty much have to prove themselves as attackers to get listed.
#22. Hyper Viper on 31 July 2007
#21. Matt on 31 July 2007
Some interesting things in this file:
Port 2222
... [more] PermitRootLogin no
MaxAuthTries 2
AllowUsers ::YOURUSER::
yep...
#20. Isolder on 31 July 2007
#19. DB on 31 July 2007
#18. SnortSam on 31 July 2007
#17. BobsUrUncle on 31 July 2007
#16. Kevin on 31 July 2007
All Operating Systems have their flaws, but I think it's like Churchill's famous dictum: "Democracy is the worst form of government, except for all those other forms that have been tried from time to time." Maybe this goes for Linux too ;)
#15. OMFG on 31 July 2007
#14. Kevin on 31 July 2007
But I wrote this article just to show people that there are different ways. And I felt iptables has a lot to offer that many of us don't know about.
Each way has it's own advantages and it's up to the end user to decide which one suits the situation best.
#13. Craig on 30 July 2007
/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j DNAT --to $ssh_server:22
/sbin/iptables -t nat -A POSTROUTING -p tcp -s #ssh_server --sport 22 -j SNAT --to $externalIP:22
#12. Juan Sabor on 30 July 2007
#11. gHOST on 30 July 2007
#10. Reid Ellis on 30 July 2007
iptables -A INPUT --protocol tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 10 -j DROP
iptables -A INPUT --protocol tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
... [more]
iptables -A INPUT --protocol tcp --dport ssh -m limit --limit 3/minute --limit-burst 2 -j ACCEPT
I got this a while back (~2-3 yrs ago?) after searching for good iptables rules, and it seemed to do the trick, stopping brute force attacks.
#9. lazy-bit.ch on 30 July 2007
#8. Casey on 30 July 2007
#7. Chuck on 30 July 2007
#6. gris on 30 July 2007
http://denyhosts.sourceforge.net/
#5. Azmith on 30 July 2007
#4. Kevin on 30 July 2007
#3. Lukas Meyer on 30 July 2007
In the beginning of the script add:
if [ "$METHOD" = loopback ]; then
exit 0
fi
... [more] ...to ensure that it isn't run on lo-interfaces.
furthermore you have the certain interfaces name in $IFACE
one could simply insert $IFACE instead of eth0. Works great if let's say, you travel a lot and change from wired to wireless networks all the time...
#2. Kevin on 30 July 2007
There should a a scrollbar. If your scroll to the right you will see that the rules are not identical. The first one identifies SSH traffic and the second one drops the traffic under specific circumstances.
SSH is TCP only, so no need for dropping UDP traffic in this example.
... [more]
Could it be that your browser is not showing the scrollbars correctly? I've tested on ubuntu/firefox2 and windows/ie6+7
#1. Bob Clay on 30 July 2007