Friday, May 9, 2008

You Say To-ma-to

I run a hacked Western Digital MyBook World Edition. It runs SSHD and with port forwarding of port 22 enabled on my router, I am able to login and access the 500Gb of storage from work.

Unfortunately this has meant opening port 22 on the router to the outside world and I was finding logs like this on the mybook recently

May 9 15:53:04 anya auth.info /usr/sbin/sshd[15612]: Failed password for root from 220.227.218.21 port 39837 ssh2
May 9 15:53:07 anya auth.info /usr/sbin/sshd[15614]: Invalid user fluffy from 220.227.218.21
May 9 15:53:07 anya auth.err /usr/sbin/sshd[15614]: error: Could not get shadow information for NOUSER
May 9 15:53:07 anya auth.info /usr/sbin/sshd[15614]: Failed password for invalid user fluffy from 220.227.218.21 port 40167 ssh2
May 9 15:53:09 anya auth.info /usr/sbin/sshd[15616]: Invalid user admin from 220.227.218.21
May 9 15:53:09 anya auth.err /usr/sbin/sshd[15616]: error: Could not get shadow information for NOUSER
May 9 15:53:09 anya auth.info /usr/sbin/sshd[15616]: Failed password for invalid user admin from 220.227.218.21 port 40408 ssh2

(If anyone wants to go visit 220.227.218.21, be my guest)

This is typical of a brute force, automated scripting attack on sshd; repeated attempts to login using a dictionary of usernames and passwords. The trick to stopping it is to recognise multiple incoming packets from the same source. A solution is described here:

Diary of a Geek

Unfortunately the solution requires iptables, the linux firewall mechanism, which needs to be compiled into the kernel. The mybook needs to be small and lightweight so does not have iptables compiled in.

However my router does. It runs Tomato which lets you do all kinds of nice linux/network related things. It's linux on a router, including iptables. Setup is via a very slick GUI, but the linux command line is there when you need it.

At first I had problems using the recent match as described in Andrew Pollock's solution as it didn't seem to be available in the Tomato setup. However a quick browse round the installation found the module was available, just not loaded. I then found that everything I needed to do (loading modules, adding new iptables rules) could be done from the Administration->Scripts section of the Tomato GUI


Figure 1. Init commands

Commands added to the Administration->Scripts->Init section are run when the router is booted up. I added

modprobe ipt_recent

to load the recent match module. Surprisingly easy. Rebooted and the previously missing module was now loaded. (use lsmod to see which modules are loaded)


Figure 2. Firewall commands

Little more complicated. I think I understand the basics of iptables now, but like quantum mechanics, anyone who claims they understand it all is lying. Here's what I added:

iptables -N wanrecent

iptables -A wanrecent -p tcp -d anya --dport 22 -m state --state NEW -m recent --name SSH_LIMIT --rsource --set
iptables -A wanrecent -p tcp -d anya --dport 22 -m state --state NEW -m recent --name SSH_LIMIT --rsource --update --seconds 60 --hitcount 4 -j LOG --log-prefix "SSH LIMIT"
iptables -A wanrecent -p tcp -d anya --dport 22 -m state --state NEW -m recent --name SSH_LIMIT --rsource --update --seconds 60 --hitcount 4 -j DROP

iptables -I wanin 1 -j wanrecent

Line 1 creates a new user table called wanrecent. this just means I can keep all this custom stuff in a single place.
Line 2 initialises a match which which keeps track of incoming NEW packets on port 22 (ssh) in a list called SSH_LIMIT.
Line 3... let's skip that as it does exactly the same as line 4 but creates a log entry in syslog instead of dropping incoming packets.
Line 4 checks if a 4th NEW packet destined for port 22 from the same source arrives, and if so simply DROPs the packet. That's the trick which is going to stop our scrip-kiddies from just firing request after request after request.
Line 5 just adds the new custom table to the existing wanin table. The wanin table contains the port forwarding rules so by inserting wan recent at position 1 it is guaranteed to execute before the forwarding. Ta-dah!

The biggest difference between what's actually happening here and in Andrew's suggestion is that wanin is part of the FORWARD table in my setup as opposed to the INPUT table. This is because the INPUT table is used when packets are destined for "this" host, the machine where iptables is running. In my case, due to port forwarding, the packets are routed through the FORWARD table.

Reboot the router it all just worked! I am hpapy.

No comments: