sshdfilter blocks the frequent brute force attacks on ssh daemons, it does this by directly reading the sshd logging output (or syslog output) and generating iptables (or ipfw) rules, the process can be quick enough to block an attack before they get a chance to enter any password at all. The blocking policy is defined by a list of blockrules largely by user name or by the type of user name. There are two install routes, the old style sshdfilter starts sshd itself, having started sshd with the -e and -D options. The newer style uses a syslog configuration line that writes sshd messages to a dedicated named pipe, normally /var/log/sshd.fifo. Regardless, this means sshdfilter can see events as they happen and act on them as they happen. sshdfilter then looks for lines of the form:
Did not receive identification string from x.x.x.x
Illegal user x from x.x.x.x
Failed password for illegal user x from x.x.x.x port x ssh2
Failed password for x from x.x.x.x port x ssh2
When sshd produces any of these messages, the response of sshdfilter is defined by the configuration file /etc/sshdfilterrc. The default configuration file defines the first message as in instant block event that will install an iptables rule dropping that IP. The other lines are given 3 chances (ie. this chance and two more) before an iptables dropping rule is generated and their IP is blocked.
These are example messages, the exact wording varies between Linux distributions, so the provided distribution configuration file sshdfilterrc exists as a large header containing default policies, and a footer directory patterns/, each file containing patterns for each Linux/sshd distribution. On installation, the header and the (hopefully) correct footer are added together to create your /etc/sshdfilterrc. All new rules are inserted into a custom iptables chain, and to prevent the chain from becoming overloaded with old rules, old rules are deleted. Rule duration is also specified in the configuration file.
Taking some statistics from my logs before sshdfilter was implemented, the longest attempt from a single IP was half an hour long, trying around 1 username/password pair per second. Over 26 days there were attacks from 42 unique IPs, none of them ever came back after the attempt. Picking the oldest 10 of these attacks, they had 347, 306, 115, 115, 127, 18, 554, 107, 9, 52 failed! password attempts. Of these 1750 attempts, 720 were for root - making a good case for blocking password authentication of the root account.
With sshdfilter installed, taking each attack on a case by case basis:
With sshdfilter installed, taking each attack on a case by case basis:
347 attempts becomes 0 attempts - first attemped guess was for a non-existant user, so was instantly blocked.
306 attempts becomes 0 attempts - same reason, non-existant user.
115 attempts becomes 1 attempt - first guess was for root and is allowed a default of 3 chances, the second guess was for a non-existant user and so was blocked anyway.
115 attempts becomes 1 attempt - same as previous.
127 attempts becomes 3 attempts - many initial guesses for root account, so sshdfilter blocks after the first 3 failed attempts.
18 attempts becomes 0 attempts - first attempted guess was for a non-existant user, so was blocked instantly.
554 attempts becomes 3 attempts - many initial guesses for root accont, so sshdfilter blocks after the first 3 failed attempts.
107 attempts becomes 1 attempt - first guess was for a valid user (nobody), second guess was for a non-existant user so was blocked.
9 attempts becomes 0 attempts - first guess was for a non-existant user so was blocked instantly.
52 attempts becomes 3 attempts - many initial guesses for root accont, so sshdfilter blocks after the first 3 failed attempts.
Summerising, of these 10 sample attacks, 1750 attempts, 720 were for root, 1013 were for illegal accounts, the rest were for existing accounts. Using only user name gusses alone, sshdfilter would have blocked 1729 of these. In fact, until the authors of the brute force attacks improve their code and send an ssh id string, sshdfilter would actually have blocked 1744 attempts, allowing only 6 guesses of the root account over an average of 6 days. Had password based root access been banned, even these six would have been futile.
Right now sshdfilter works with Debian 3.1 to sid, Redhat 7.3 to 9.0, Fedora Core 2-4, CentOS, Suse 10.0 RC 1, RedHat Enterprise Linux 4, Slackware and gentoo, and the many derivatives. It also supports Mac OS X. Each distribution uses different logging messages, so sshdfilter needs a pattern list for the target system. Patterns are supplied for RedHat 7.3 and 9.0 systems, RedHat Fedora Core 3 systems, Suse 10.0 RC 1 and Debian 3.1 (sarge, stable) systems, the other distributions use patterns based on these 4.
An older version can be found here(V1.5.3).
Newest version with ipfw support can be found here(V1.5.5).
A preconfigured Mac OS X package can be found offsite here.
Older versions can be found at on their own page here.
sshdfilter was written with common Linux distributions in mind, and so expects to find perl, the iptables command (or ipfw command) and support syslog style logging. For the details, see INSTALL and INSTALL.ipfw.
All previous ToDos have been implemented.
1. Write a corresponding LogWatch script.
2. Write an automated install.pl script. This has been attempted, would like some feedback on how well it worked for you.
3. Rewrite above case by case examples, default policy is now to allow illegal user names 3 chances, rather than 0 chances.
4. Support for CentOS 5, which uses multi-line sshd messages - though I've since had reports that sshdfilter works okay.
5. Different method of getting the sshd pid when running mulitple sshds with install route 2. Current method is impractical.
6. Update the patterns to account for the many new sshd style messages, in some cases sshdfilter will work but the docs don't say so.
Some common questions and other bits of information can be found here in the FAQ, which is aimed at pre 1.5 but some issues, like the problems created by firewall generators will still apply.
V1.0 Initial test release, trialed on RH7.3 and RH9 machines.
V1.2.x 5/6/2005 Added subprocess so sshd could have its own log entry, this avoids confusing LogWatch type programs, so only the sshdfilter output needs a new log parser. This is also the first web release.
V1.3.x 9/6/2005 Added config file and easier support for different logging messages, as so many distros like to use different messages for the same thing.
V1.4.x 20/10/2005 Daemonise and use select()
V1.5.0 12/6/2006
1. Rewrote the configuration parser and the pattern matching engine, this should provide all the flexibility you could ever want.
2. sshdfilter can now read sshd messages from either sshd -eD(used by all previous versions of sshdfilter), or via a named pipe maintained by syslog.
V1.5.1 6/7/2006 (Thanks to Tommo)
1. Config file contained a spurious line, and spurious sshd patterns.
2. Source code wrongly refered to /etc/sshdfilterrc15.
V1.5.2 17/11/2006
1. Fixed bug that made sshdiflter quit if reading from a pipe and syslog restarted.
The pipe is now reopened.
2. Fixed bug in sshdfilter startup script (route 2 style), 'restart'/'stop' was broken, killall
also killed the startup script because it had the same name.
3. Fixed a few typos.
4. Wrote install scripts for both sshd wrapper and standalone installation options.
V1.5.3 14/1/2007
1. Added hostname lookup for messages. Some PAM based systems shows source hostnames, never source IP.
2. Added hostname based pattern for Debian 3.1 system.
3. Added config error checking, tells the user if they forgot to include machine specific patterns.
4. Cleaned up code that reopens the named pipe when syslog restarts.
5. Removed many errors from the alpha quality auto install scripts, should now have some chance of working.
6. Improved standalone startup script, /usr/local/sbin is not always in the PATH.
V1.5.4 8/4/2007
1. Added ipfw support, thanks to Ronald Rood for preliminary testing on Mac OS X.
2. Changed options to be more firewall command neutral.
3. Added pattern "User ... not allowed ... not in AllowUsers", thanks to Ian Denton.
Written by Greg: greg at csc liv ac uk. Would welcome any comments.
This software is released under the terms of the GNU GPL.