DenyHosts Python and grumpy Ubuntu staff


I’m a keen user of Denyhosts to protect SSH boxes, especially on cheap NAS boxes with fixed libraries/distros. It’s runs on Python 2.3 and above and most of the cheap boxes are now capable of running that and you don’t need to try and match libraries and old versions to get something useful. I know there are newer tools available like fail2ban but DenyHosts can save you on a hacked NAS where no other options exist.

As part of my security practices (and sometimes going around SSH port blocking on corporate firewalls) I occasionally move SSH to other ports using “listenaddress” or “port” in sshd_config or by setting a NAT rule on the edge router. One symptom of this I’ve noticed with 80/443 (yes I know!) is that Denyhosts doesn’t automatically block “Bad protocol” hits as they’re not actually attempts to sign in. I take the view they’re still unwanted as they’re likely to be scanning ranges, and by definition could be back later to try SSH on the host they’ve found. I spotted the USERDEF_FAILED_ENTRY_REGEX in the denyhosts FAQ. I didn’t understand what a regex is as I know nothing about Python but it seemed the answer so I googled and found a rather odd response to the same question in the Ubuntu forums. Back in 2008 Anthro398 had a similar question and got shot down by a staffer as they didn’t seem to quite get it. I thought Anthro398 was perfectly sensible (am I wrong too??) but never got any help… just an argument. Now I get particularly annoyed at sort of attitude, but the good thing was Anthro398 had given a snippet of code –  USERDEF_FAILED_ENTRY_REGEX=sshd.*Bad protocol version identification.* from (::ffff:)?(?P<host>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) which didn’t work but at least gave me something to go off.

Being a python and regex numnutz I also found the python regex checker to help me learn: , pasting the code from Anthro398 into it plus a snip of my /var/log/messages containing the hits showed the code was broken. After a bit of reading, experimenting in pythex and trying in one of my denyhosts instances I found the mistake. Removing the leading sshd.* was part of the problem as denyhosts parses that elsewhere (don’t ask me I don’t know) then just a change of a : to a ? and it all burst into life! I also managed to lock my IP out of denyhosts by web browsing the box testing it!! As I’d maintained an SSH I could still edit the config and you may also want to look at this FAQ too if you do the same, just removing the IP from /etc/hosts.deny isn’t enough as denyhosts will pop it back in from its working files.


So thanks to Anthro398 for all your work, you were nearly there; I considered contributing to the thread but would have to register and then I’d probably get flamed for the temerity to think a little differently about how I set up systems. So I’ll just leave the correct regex here in case anyone wants to use it. Just stop denyhosts and modify denyhosts.cfg to include : USERDEF_FAILED_ENTRY_REGEX=Bad protocol version identification.* from (?:ffff:)?(?P<host>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) before restarting the service again.

All the ususal things apply – consider carefully the risks exposing any SSH or web on a box you may not be able to patch properly, the risk of losing the data on it versus the reason for having it there. Read up on SSH hardening, really really try and set up Key based authentication and disable passwords if you can, at least have key as the default!