Stopping SSH & FTP brute force attacks with IPFW
Saturday, December 6, 2008 19:48
Brute force attacks are becoming more and more common in todays security landscape; if you receive security cron logs from your FreeBSD server you will know exactly what I mean. These attacks usually use automated software to try thousands of username and password combinations on SSH and FTP, continually aiming to find a weak account on your system and exploit it.
If an attacker can get access to one system account, that is the first step to doing some very bad things on your system, a nightmare for users and administrators. Luckily, there is a way to stop these attacks, and they’re freely available in the ports collection.
IPTables on Linux has the ability to dynamically add rules to block brute force attacks, however IPFW, a widely used firewall and packet filter, does not have an ability. We are forced to turn to look for 3rd party apps, lucky for us there are some very good ones out there, and we will look at 2 here.
Before we start, we will need to make sure ipfw is enabled in the kernel:
# ipfw show
If you receive an error like this:
ipfw: getsockopt(IP_FW_GET): Protocol not available
then IPFW is not enabled. You can learn how to enable it over here.
SSHGuard
The first one I looked at when trying to solve this problem was SSHGuard. It is available in the ports and is very easy to implement (This tutorial assumes you understand how to build and install ports; if not, consult the FreeBSD documentation). SSHGuard actually support all major firewall software, however for the purpose of this tutorial I am using the IPFW version.
To install, simply run this:
# cd /usr/ports/security/sshguard-ipfw; make install
Once that is built, open /etc/syslog.conf, uncomment the line added by SSHGuard, and save. Then all we need to do is reload the syslog configuration:
# /etc/rc.d/syslogd restart
Congratulations, SSHGuard is now up and running!
The good thing about SSHGuard is the rules work for common software right out of the box, so if you are running OpenSSH, you can close this window because your job is done. However, like I found, if you run something else (Commercial SSH for example), it will not add the rules as it does not have support for its log format. The only way to add rules to is request them from the vendor, which is not ideal. Which brings us to our second solution.
BruteBlock
After needing a custom ruleset, I stumbled upon BruteBlock, which allowed custom rulesets using regular expressions. Installation of this is not quite as simple, but still fairly easy:
cd /usr/ports/security/bruteblock; make install
Once it is installed, we can look at our rulesets, located in /usr/local/etc/bruteblock/ssh.conf. As you can see there is already some rules there for OpenSSH, but lets add a rule for Commercial SSH 2.
regexp2 = sshd2.*connection from \”(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\”
This will add our ruleset to catch connections through SSH. If you fee like tinkering with the amount settings and times, this is the place to do it, however the defaults should be ok.
Now we need to tell the system we want to use bruteblock. This is achieved by editing /etc/rc.conf:
bruteblockd_enable=”YES” (is enabled YES)
bruteblockd_table=”1″ (Which table – 1)
bruteblockd_flags=”-s 60″ (How frequently to review the ipfw table for entry removal)
Next, lets add a rule to the firewall. This creates a “table”, a list of IPs that will all have a common firewall rule attached to them, in this case deny everything:
add deny ip from table(1) to any
You can add this to /etc/rc.firewall to have it load automatically on boot.
Now lets modify the syslog conf again, this time for bruteforce:
auth.info;authpriv.info |exec /usr/local/sbin/bruteblock -f /usr/local/etc/bruteblock/ssh.conf
Now lets start bruteblock:
/usr/local/etc/rc.d/bruteblockd.sh start
Great, now reload the rules as was shown earlier in this piece. You should now be all set. You can check blockd IPs in this way:
ipfw table 1 list
And there you have it, two solutions for stopping brute-forcers dead in their tracks. One less security issue to worry about.
No related posts.

(4 votes, average: 4.75 out of 5)
stoneyjackson (Chris Buckley) says:
December 7th, 2008 at 12:19 am
Stopping ssh and ftp brute force attacks on FreeBSD using IPFW – http://bit.ly/FA45
Mxx says:
December 14th, 2008 at 4:34 am
NIce useful stuff here!
Kevin says:
March 12th, 2009 at 4:21 pm
I’m using a different method: change ports for ssh/ftp (make it over 8000), also configure:
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
in /etc/sysctl.conf
The automate scans are completely eliminated.
I have blogged it, you can search the posts on my blog.
dr.hoffman says:
March 27th, 2009 at 3:45 am
*Please, Disregard previous post*
Great article – Thanx!
Very Helpful!
Please, note that string:
add deny ip from table(1) to any
Should look like:
add deny ip from table\(1\ )to any
– with reverse slashes
KC says:
April 17th, 2009 at 5:10 am
Thanks for the information! It helps a lot!
James S says:
July 2nd, 2009 at 8:44 pm
I’m not familiar with ipfw, since I don’t need or want a firewall for any other reason than to use BruteBlock. I keep getting a:
bruteblock[1083]: Blocking failed for (my test attacking IP)
I am running firewall_type=”OPEN”, because as I said, I really don’t want to have IPFW interfering with anything else. If I do a: ipfw table 1 list, I do see the same test IP listed, but it is not being blocked.
I’d appreciate a clue or two…if I need to run the firewall differently, how best to do that as simply as possible.
Thanks!
Chris says:
July 3rd, 2009 at 1:52 am
Send me your ssh.conf (bruteblock), rc.firewall (ipfw) and you syslog.conf (syslogd) and I’ll take a look for you. chris [at] reallfreebsdtips [dot] com
SoniXAnT says:
July 19th, 2009 at 2:59 pm
Two tips for bruteblock:
1) ipfw acts as a “firts match first win” firewall so add the deny rule BEFORE any other ruleset
2) I can’t understand why my syslogd doesn’t recognize bruteblock from my syslog.conf, if this is your case, here is a workaround:
just add the following line to your /etc/rc.local
echo “tail -F -n1 /var/log/auth.log | exec /usr/local/sbin/bruteblock -f /usr/local/etc/bruteblock/ssh.conf &” >> /etc/rc.local
and reboot
hope this helps!
SoniXAnT says:
July 19th, 2009 at 3:06 pm
Oops, sorry I meant:
tail -F -n1 /var/log/auth.log | exec /usr/local/sbin/bruteblock -f /usr/local/etc/bruteblock/ssh.conf &
do not forget the final \&\ or else init will be stuck in the tail command from the next reboot
Chris says:
July 20th, 2009 at 11:49 am
Great tip, I couldn’t have said it better myself. I found that putting the bruteblock line up the top of your syslog.conf file guarantees it will start correctly. Let me know how this goes for you.
SoniXAnT says:
July 21st, 2009 at 3:30 am
Yessss, now it works!! The bruteblock line must be put at the top of syslog.conf as you said…strange issue nevertheless.
Chris says:
July 21st, 2009 at 12:02 pm
Glad to hear it. :)