~#nixy

Nix is sexy

Archive for the ‘sshd’


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 you
  • HOSTS_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!