DenyHosts on FreeBSD 6.2
If you run a nix server for a little while, you’ll notice that bots will try to gain illegitimate access to your server through ssh. While this unsettles a lot of people, there’s really nothing to worry about as long as you don’t permit root logins (Many Linux distributions allow direct root login via ssh by default) and have a strong password policy.
Nonetheless, taking just an extra measure of security is a good idea, and this is where DenyHosts comes into the picture. DenyHosts is a small Python script which makes password-guessing on your OpenSSH deployments virtually impossible, by allowing only a limited number of login attempts to your sshd. After a set number of tries, DenyHosts simply denies the given IP further attempts. What’s even cooler about DenyHosts, is that the most recent version (2.0) allows you to benefit from over 23.400 other peoples ban lists, thus meaning you’re saving yourself a lot of worrying about those pesky login attempts. An added bonus is that you’ll save yourself a few kB’s of network traffic and a few CPU cycles by straight-out denying any previous offenders a connection to your server. :)
Other people might just want to save themselves the trouble, and move their sshd to a different port. I believe that this solution is just security through obscurity, and is dangerous in the way that it gives a false sense of security to the admin. I disagree with that kind of solution, as you might notice if you look at the comments the article in question has generated. (Please notice that even though I disagree with his method of avoiding sshd bots, I deeply respect the work that Dan is putting into The FreeBSD Diary.)
DenyHosts depends on Python, which you have to make sure you want to have on your server. Python isn’t such a bad thing to have – but porting DenyHosts to sh would certainly reduce the amount of CPU cycles needed, and of course, remove Python as a dependency for those who don’t want to bloat their server.
So let’s get started, shall we?
First, make sure that you’ve got the updated ports tree (Use portsnap) and install the security/denyhosts port. If you’ve already got Python, this should only take a few seconds, as nothing needs to be compiled.
Once installed, DenyHosts gives you a lot of info about how to configure it, but I’ll repeat it just in case.
Open /etc/rc.conf, add the lines
denyhosts_enable="YES"
syslogd_flags="-c"
The first line ensures that DenyHosts starts at boot time. The second line makes sure that syslogd does not group repeated log messages, so that they appear as “Last line repeated 23234 times” – This makes it possible for DenyHosts to actually count how many login attempts any given hosts has made.
Now edit /etc/hosts.allow and add the lines
sshd : /etc/hosts.deniedssh : deny
sshd : ALL : allow
This will ensure that the hosts.allow mechanism in FreeBSD denies connections to your sshd from any of the hosts listed in hosts.deniedssh, and allows all other connections. The last line parsed is authoritative, so in theory if you add an IP to the block list in hosts.deniedssh, and allow the same IP later in the parsing process, the host will be allowed to connect.
Before we go further, we need to make sure that the hosts.deniedssh file exists and has the correct permissions:
touch hosts.deniedssh
chmod 644 hosts.deniedssh
chown root:wheel hosts.deniedssh
Almost there. For good measure, we should probably edit the /usr/local/etc/denyhosts.conf. If it’s not there, copy over denyhosts.conf-dist to denyhosts.conf, and fire up your favorite editor.
Make sure to read every single line of the sample configuration file, and adjust the settings to whatever fits your system and preferences. The most vital options here are the:
SECURE_LOG, which should be /var/log/auth.log, just in case the “Mandrake, FreeBSD or OpenBSD” comment right above it confused youHOSTS_DENY, should be set to /etc/hosts.deniedssh just in case you forgot which file you were creating a second ago
All of the timing and recurrency options are quite sane defaults, so I’d recommend you not to touch them unless you either know what you’re doing, or if you’re very picky about these kinds of things.
Now you should have a nicely working DenyHosts installation, but wait, remember the 23.400 people who are contributing to the DenyHosts lists? Why not be a part of this amazing network? All it requires, is that you enable the synchronization feature. Just uncomment the SYNC_SERVER variable, and synchronization will work fine.
The reason why synchronization isn’t enabled by default even though it’s the optimal setting for the vast majority of installations, is because synchronization poses a theoretical security risk, and a theoretical privacy risk.
The security risk is – as I said – purely theoretical, as if some evil hacker was to be pissed off by all these people who are not responding to his ssh-bots, and should decide to hack the denyhosts synchronization server, he could send malicious code to all synchronizing DenyHosts clients. Remember, though, that this risk is as improbable as the sky falling down on our heads, and that anybody can buy a license to use the synchronization server for use in their private network. You could also reverse engineer the synchronization protocol that DenyHosts uses and make your own synchronization server – But then again, this entire paragraph consists solely of theoretical possibilities.
All that’s left to done is to restart the system (To make sure syslogd starts with the -c flag) and to make sure DenyHosts has started at boot time.
ps -ax|grep denyhosts
If you enabled synchronization, you can also watch as DenyHosts fills up the hosts.deniedssh file with lots and lots of persistent sshd-brute forcing zombies. Dare to cat it?
Enjoy your new non-obscurely secured sshd!
October 12th, 2007 at 00:29
Excellent post! It is these kind of tips, that are invaluable.
There has probably been written about DenyHosts before (no doubt about it). But these kind of things can’t be mentioned too often – especially when there are so many, including myself who are toying with self hosting. It is after all our own responsibility to have an adequately hardenend server, so they aren’t abused as spam relays or being used in botnets.
I love DenyHosts, and it has caught around 600 different IP’s that have tried brute force attacks on my server.
I probably wouldn’t have chosen Python to write it in, if it was my choice – mostly because I really don’t know anything about Python, so I don’t know it’s strengths, but I wouldn’t chooose sh scripting either. Sh can’t really do all that much, so to do pattern matching, text editing and so on, you would have to use grep, sed, awk, etc. Which means you would have to spawn new processes which comes with an overhead. Instead I would have gone with Perl – almost every *nix has Perl installed as part of the core distribution, and it is perfect for text manipulation.
Sorry for the little sidestep. I love DenyHosts and this post!
October 12th, 2007 at 00:32
Thanks for the comment.
You’re right. Perl would actually be ideal.
And we’re way too few self-hosters who know what we’re doing.
October 15th, 2007 at 19:45
I’ve been using DenyHosts on FreeBSD for a while now, but I’m not a big fan of tcpwrappers. Luckily, it’s pretty trivial to setup pf to use the DenyHosts file as a table, then just use the “plugin” feature of DenyHosts to fire off a script to update the table when it add/removes addresses.
October 15th, 2007 at 20:41
@2bithacker
Nice, maybe I should write an addendum for my article about that. I use ipfilter, though.
October 16th, 2007 at 13:42
is it similar to sshit?
sshit analyzes auth.log in real time and blocks connection thru ipf or ipfw.
October 16th, 2007 at 13:43
Yes, in that way it is similar – Except that you don’t have to run ipf or ipfw on your box to use it, and the distributed database is also kind of neat :)
October 17th, 2007 at 00:12
[...] Learn how to set it up here [...]
October 17th, 2007 at 01:18
DenyHosts reportedly has known unfixed DoS vulnerabilities that allow anyone to lock all hosts out of your SSH. Details:
http://www.ossec.net/en/attacking-loganalysis.html#denyhosts
October 17th, 2007 at 01:39
I use SSHIT and yeah doesn’t have the distrubuted list aspect, but otherwise just works… Oh and it’s written in perl… always a plus.
October 17th, 2007 at 10:05
Look for the bruteblock. Wonderful programm!
/usr/ports/security/bruteblock
pkg-descr:
Bruteblock allows system administrators to block various bruteforce
attacks on UNIX services. The program analyzes system logs and adds
attacker’s IP address into ipfw2 table effectively blocking them.
Addresses are automatically removed from the table after specified
amount of time. Bruteblock uses regular expressions to parse logs,
which provides flexibility allowing it to be used with almost any
network service. Bruteblock is written in pure C, doesn’t use any
external programs and work with ipfw2 tables via raw sockets API.
October 18th, 2007 at 00:25
Another good program of this type is bruteforceblocker (available in the ports as security/bruteforceblocker or from http://danger.rulez.sk/projects/bruteforceblocker/)
It is written in perl, easy to install, and like DenyHosts it gives you the benefit of synchronizing with a master table generated by all the other people running it.
Unlike DenyHosts, it uses a firewall table instead of tcpwrappers, so if you have a BSD or linux firewall protecting your network, one instance of BruteForceBlocker can stop ssh attacks on your entire network just as easily as it can protect a single host.
It was designed for OpenBSD pf, but can be trivially adapted to ipfilter, ipfw (or iptables for the linux types).
October 22nd, 2007 at 23:20
[...] extra security, and you might too. Just right off the bat I can mention things like httpd, sshd, denyhosts, and syslog-ng. While the theoretical risk of these applications crashing randomly and still being [...]
October 23rd, 2007 at 13:49
Why to use such a programs, when you can use pf to block everything and allow just a few IP’s from which you can connect to port 22.
October 23rd, 2007 at 19:09
@bichumo
1. Because I often connect from my mobile phone using MidpSSH
2. Because I often connect from machines which are not my own
3. Because you might be sharing the ssh access with other people
=)
October 24th, 2007 at 11:38
surprisingly, nobody knows pam_af ?
Port: pam_af-1.0.1
Path: /usr/ports/security/pam_af
Info: Anti-bruteforce PAM module
WWW: http://mbsd.msk.ru/stas/pam_af.html
Light, any pam service (ssh/ftp/…) can be anti-bruteforced !
http://uvblues.blogspot.com/ for a quick/dirty setup
April 28th, 2008 at 22:40
Great post and thanks!
I wish I could point it at HTTP logs for brute force attacks against my .htaccess
There are an awful lot of people trying to access my phpmyadmin alias.
June 26th, 2008 at 23:02
[...] Learn how to set it up here « FreeBSD: the best server OS Google Docs updates » [...]
March 15th, 2009 at 22:38
Great article. One note that might be of interest: in addition to your suggestions, the denyhosts faq mentions blanking out the BLOCK_SERVICE value when using auxiliary files.
http://denyhosts.sourceforge.net/faq.html#aux
Can anyone comment on why this might be?
Also, any comments on how to block ALL access from the offending hosts? This seems doable, but the tutorials and documentation seem to suggest the approach of just blocking ssh. Maybe this is to prevent a DoS to all your services at once if someone’s injecting code?