It's too dangerous to go alone. Take this.

Archive for November, 2009

Report SSH login attempts over Growl

Shortly after subscribing for a linode VPS, I started getting very paranoid about computer security. It had something to do with seeing SSH produce page after page of log output that looked like this:

Nov  1 21:42:13 li30-243 sshd[3223]: Invalid user festival from
Nov  1 21:56:30 li30-243 sshd[4991]: Invalid user florian from
Nov  1 21:58:09 li30-243 sshd[5185]: Invalid user fm from
Nov  1 22:00:03 li30-243 sshd[5429]: Invalid user foo from

This is a pretty blatant dictionary attack. And my machine gets peppered with these sorts of attacks constantly. All day, every day. What’s worse is that it’s coming from multiple computers at the same time. What was even more scary was when I noticed similar log output on my macbook pro at my apartment! One good idea is to use something like DenyHosts to automatically block IPs that have too many failed authorizations in a row. In the case of this kind of distributed attack, though, DenyHosts won’t help much. But since login attempts to your personal home Mac should be rare, it’s nice to have them brought to your attention. That’s why I wrote a simple intrusion detection script that issues Growl alerts. I call it, the SID Growler. Not much explanation for this one, because it should be pretty obvious how it works. Let me know if you have any questions though!

#!/usr/bin/env bash

# Watch the OS X secure log and show growl notifications when important events
# happen

authentication error


function stripLogPrefix
    awk '{
            for (i = 6; i < NF; i++)
                printf $i" ";
            printf "\n";

IFS="|" # Separate pattern chunks with the pipe character for egrep
tail -F $LOGFILE | grep --line-buffered sshd |
    egrep --line-buffered "${PATTERNS[*]}" | stripLogPrefix |
        while read line; do

            TITLE="SID Growler"
            MESSAGE="Message: $line"

            growlnotify --appIcon "Keychain Access" $TITLE -m "$MESSAGE"


In order to run it, of course, you must either use sudo or have a shell owned by root because /var/log/secure.log is owned by root.