Prevent SSH Brute Force attacks

When checking logfiles, I often can see brute force attacks – especially against the ssh daemon.
Of course, best way would be to block all ssh traffic except from your office/home ip.
If this is not possible for various reasons, you can make life a little harder for “intruders” using iptables.
 
Aim:
If there are more than three connection attemps within 120 seconds,
all traffic from potential attacker to ssh port (tcp, 22) shall be blocked temporarily.
 

#!/bin/bash
#
IPTABLES=`which iptables`
#
### if more than three new connections in 120 sec -> log
$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent \
--rcheck --seconds 120 --hitcount 3 --rttl --name SSH -j LOG --log-level 7 \
--log-prefix "Possible SSH breakin attemp: "
#
### if more than three new connections in 120 sec -> drop requests
$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent \
--update --seconds 120 --hitcount 3 --rttl --name SSH -j DROP
#
### remember new, established connections
$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent \
--set --name SSH -j ACCEPT
#
### generally allow ssh connections
$IPTABLES -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
#
# ---
# -I INPUT .. -> iptables chain
# -i eth0 ... -> interface to apply rule to
# -p tcp .... -> use tcp port
# --dport ... -> destination port 22 (SSH)
# -m recent . -> matching state
# --state ... -> can be NEW, ESTABLISHED, RELATED or INVALID
# -rcheck ... -> will check if the source address of the packet is currently in the list
# ---

 
 
If it works, you should see entries like this in your firewall log
(i.e. in /var/log/firewall [ openSuSE ]):
 

Feb 28 15:14:20 cypher kernel: Possible SSH breakin attemp: IN=eth0 OUT= MAC=00:0c:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx SRC=123.xxx.xxx.xxx DST=223.xxx.xxx.xxx LEN=60 TOS=0x00 PREC=0x00 TTL=59 ID=52858 DF PROTO=TCP SPT=38220 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0

exim graphs

Because I did not found a tool to create graphs (the way I want it)
from exim logs, I wrote a little bash script that suits my needs.
 
Example graph:
 
mailfilter graph
 
Download: exim_rrd-0.9.5.1 (updated 2009-03-07 [bugfix])
 
I’m not a programmer, so the script can be improved – no question : )
If you have any hints, please tell me.
 
 
Usage: run as cronjob, i.e.
# mail statistic
*/5 * * * * /usr/local/bin/exim_rrd > /dev/null 2> /dev/null

 
 
dependencies:
rrdtool [ http://oss.oetiker.ch/rrdtool/ ] ^ thanks to Tobias Oetiker
(e)grep
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
tested with:
rrdtool 1.2.23, rrdtool 1.2.27
openSUSE 10.3 (i586), exim 4.69 main log
openSUSE 11.0 (i586), exim 4.69 main log