Monday, June 06, 2005

OpenBSD SSH Protection

As may become apparent over time, I'm a Unix Geek. Each flavour is special in its own little way. My favourite for exposing to the 'Net is OpenBSD. But the problem I have with my current machines is that script kiddies keep trawling trying to get in over SSH, etc. So what I've done (inspired by DenyHosts) is write a small shell script to keep an eye on my authlogs and block offenders.

DenyHosts looks interest, and earns brownie points from me being written in Python. But I just need something to be small and specific. Also, DenyHosts only adds entries to your hosts.deny file, and I want to block all access from these little buggers!

OpenBSD ships with a good firewall. The approach I took was to parse my log files for people trying to get in via SSH and failing (with a bit of extra logic to stop it booting me if I do something silly) and then simply add offending IP addresses to the firewall as blocked hosts.

Here's the script that does the work: (it's messy, I know, but it works)
#!/bin/ksh
#
# Script to trawl logs for nastiness and log bad IP addresses
#

NUM_TRIES=3

SSH_INVALID_USERS=`grep 'Invalid user' /var/log/authlog | awk '{ print $10 }' | sort -u`

for iu in $SSH_INVALID_USERS; do
   num=`grep $iu /var/log/authlog | wc -l`
   if [ $num -gt $NUM_TRIES ]; then
     echo "$iu" >> /var/tmp/invalid_users.list
   fi
done

cat /var/tmp/invalid_users.list | sort -u > /var/tmp/invalid_users.list

SSH_FAILED_PASSWORD=`grep 'Failed password for' /var/log/authlog | grep -v 'invalid user' | awk '{ print $11 }' | sort -u`

for fp in $SSH_FAILED_PASSWORD; do
   num=`grep $fp /var/log/authlog | wc -l`
   if [ $num -gt $NUM_TRIES ]; then
     echo "$fp" >> /var/tmp/failed_passwords.list
   fi
done

cat /var/tmp/failed_passwords.list | sort -u > /var/tmp/failed_passwords.list

cat /var/tmp/invalid_users.list /var/tmp/failed_passwords.list | sort -u > /var/tmp/blockers.list

pfctl -t kiddies -vTadd -f /var/tmp/blockers.list
This script, run from cron as root, will update the kiddies table with bad IP addresses.

Here's the entries from the pf.conf file (firewall configuration) that does the work:
ext_if="vr0"
table <kiddies> persist
block in on $ext_if from <kiddies>
And that's all there is to it! If you want to see how effective you're being, you can run something like:
pfctl -t kiddies -vTshow

1 Comments:

Blogger Phill said...

Nice one! Just what I was looking for. Thanks!

25/1/10 01:59  

Post a Comment

<< Home