Thursday Night

Paul Betts’s personal website / blog / what-have-you

Kicking out SSH script kiddies with autoblock

I noticed recently that random people have been trying to brute-force SSH on this website – this is a pretty common thing to notice among Linux users unfortunately. Things like this will often appear in your logs (On Debian/Ubuntu it’s in /var/log/auth.log):

Failed password for invalid user pete from 72.22.77.196 port 59102 ssh2
Invalid user peter from 72.22.77.196
(pam_unix) check pass; user unknown
(pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=72.22.77.196
Failed password for invalid user peter from 72.22.77.196 port 59251 ssh2
Invalid user peter from 72.22.77.196
(pam_unix) check pass; user unknown
(pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=72.22.77.196
Failed password for invalid user peter from 72.22.77.196 port 59494 ssh2
Invalid user phil from 72.22.77.196
(pam_unix) check pass; user unknown
(pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=72.22.77.196

Thanks 72.22.77.196, you’re a giant tool. So to get rid of you and your ilk, I wrote this Ruby script:

#!/usr/bin/ruby
ip_count = {}
blacklisted = {}
tables = `iptables –list`
STDIN.readlines.each do |x|
        next unless x =~ /Failed.*ssh2/
        m =  /(\d*\.\d*\.\d*\.\d*)/.match(x)
        next unless m and m[0];  addr = m[0]
        ip_count[addr] ||= 0; ip_count[addr] += 1
        next unless ip_count[addr] > 10
        next if blacklisted[addr] or tables.include? addr
        `iptables -I INPUT -s #{addr} -j DROP`
        blacklisted[addr] = true
end

Since the auth log is called different things depending on your distro, I made the script run from standard input. To make it run every half-hour, run crontab -e and add the following line:

0,30 * * * * cat /var/log/auth.log | ruby /root/ssh_block.rb

Written by Paul Betts

April 11th, 2007 at 11:19 am

Posted in Linux