14/02/2006 @19:14:22 ^20:10:26
They couldn't have picked a better date for this!!
my version of the "protect yourself against ssh dictionary attacks" post
So a few weeks ago I finally got fed up of my modem lights flashing uselessly for anything up to an hour at a time and my log files filling up with sshd errors, so I did this. Yeah I know about 50 million sites have already written their own posts on this topic but I don't care!
sshd_config stuff
In your /etc/ssh/sshd_config you can do this
- PasswordAuthentication no
Attacks generally use plain password authentication, that is, where a username/password combination is sent over an encrypted channel. Most proper ssh clients support something better, so you can turn it off. Please note password authentication is different from keyboard-interactive; you can still log in with your unix password if PAM or whatever allows it. I didn't realise this for a while and was very puzzled when I found I could still log in using I think keyboard-interactive is harder to fake for a remote worm. - PermitRootLogin no
I think it's probably safer to disallow root access completely. Log in via a regular user and use sudo or something. However if like me you're lazy and have set it up so you can sudo anything and someone else has your password you're still just as screwed. However a remote attacker knows there's a root account on your system, but won't necessarily know the name of your normal user login. I don't know, just be vigilant and don't use stupid passwords I guess.
iptables recent match
Combined with a decent user password, the above is probably enough to protect you against random ssh attacks. But you'll still see log file activity and modem lights and whatever. How about cutting them off completely at the firewall? Various people have come up with ways to use the iptables recent match to drop packets from hosts that spam you with ssh connections. This is mine. It is very simple.
Before you just had what amounts to this:
- iptables -t filter -A INPUT -p tcp --dport 22 -m state NEW -j ACCEPT
Now you do this (new stuff in bold, obviously)
- iptables -t filter -A INPUT -m recent --update --hitcount 5 --seconds 30 -j DROP
- iptables -t filter -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set -j ACCEPT
Vague explanation: instead of blindly accepting the connection, you tell the recent matcher to make a note of it. Then, before that, you tell the recent matcher to drop the connection if it's had 5 similar connections in the previous 30 seconds. We use --update so that the outsider has to go fully 30 seconds with no connection attempts before the matcher starts letting him in again.
It's not ideal yet, I mean, I would like to be able to drop people who spam 5 times in 30 seconds for a full hour, but I haven't worked out how to do that yet. Anyway this seems to work as the current breed of worm seems to stop scanning you if it detects that you are no longer accepting connections, I guess so that it doesn't get stuck in tarpits or whatever.