revised ssh/ipf blocking on netbsd

Update 08jan06 @ 08:05: After sending this link to Hubert he came back with a change to get the sed lines inside the shell, so I’ve updated the post to reflect this as it’s a far neater solution.

Ok, I couldn’t resist the challenge after Hubert blogged about my pop-before-smtp script, so here’s my rather ugly shell version. Sadly, I’m lousy at sorting out shell escaping so as well as the shell script there is also a sed script that does the log file filtering: please feel free to alter things to work in one shell script – the code is mine, but do with it what you will, as it doesn’t really have much to it in the end (click on the filenames to get the source).

block.sh:

#!/bin/sh
  
# Block unauthorised login attempts using only system tools
# Inspired by Hubert Freyer's 'challenge' to write a script that just used
# tail to do the work
# (c) Ian Spray and Hubert Fyerer, 2006
  
# Use it for what you will: no restrictions, and no warranty
  
TAIL=/usr/bin/tail
SED=/usr/bin/sed
IPF=/sbin/ipf
CMD_PERM='/usr/bin/tee -a /etc/ipf.conf | '
LOG_FILE='/var/log/authlog'
SED_PAT=ip.sed
  
# uncomment the following line if you want bans to be temporary
# CMD_PERM=''
  
${TAIL} -F ${LOG_FILE} | while read LOG_LINE
do
	echo ${LOG_LINE} 
	| ${SED} 
		-e '/127\.0\.0\.1/d'  \
		-e '/192\.168\.0\./d' \
		-e '/Failed password .* from/!d' \
		-e 's/.*Failed password .* from \([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3}\).*/block in log quick from \1.\2.\3.\4 to any/' \
	| ${CMD_PERM} ${IPF} -A -f -
done 

Note the two main features are the -F in the tail to ensure that log rotations don’t kill the script (check your version if porting outside of NetBSD) and the while loop is to prevent sed from block buffering the log file data. The very long line that performs the actual cutting of the IP address doesn’t fit well on the web, so grab the source if you want to read it easily.

Note that you ought to replace your own LAN subnet (and trusted external site ?) at the start of the sed script to prevent unfortunate accidents, and that the text has been broken to try and fit it more cleanly on the web page: download the file for the correct source code.

If an annotated version of these is desired, then let me know and I’ll explain as much of it as I can remember 🙂

The original downloads are: old_block.sh and ip.sed

← Previous Post

Next Post →

4 Comments

  1. Ah, that looks like a relative URL issue for the RSS version – thanks for the notice, I’ve fixed them all up to be absolute now.

  2. Am I right that this skript just blocks an IP outside of the excludes rages if there is a failed login attempt?

    Bad idea if you are outside your home-net, try to log in and get your password or username false… I think it would be better just to look for the usernames that are used in the attacks but not on your system.

  3. You’re correct in the reading of this script Ingo, and yes it is 100% possible to lock yourself out of your own system with the script as it stands. I have a few external trusted machines that I have accounts on added into the top of the exception list so that won’t happen to me: I also trust the ssh AllowUsers directive to deny requests for invalid usernames, but am much more worried about protecting the real usernames from attack, as statistically they actually have a chance of succeeding.

    If you use keys to log in, there’s also no chance of getting caught here unless the machine you have keys on has been used to try and hack into your account by someone who doesn’t know about the keys – whilst inconvenient it’s something that you really want to know about before it succeeds. If this is a possibility, then it might be worth using the pop-before-smtp variant with an expiry time so you do get a second chance.