The SSH attack activity has continued to get more aggressive. Of course, the best defense is to have good passwords. However, there are a few other things you can do to protect yourself. The article at Whitedust Security has some background and a few things that can be done as a starting point. Whitedust seems to only think that this problem started in May, when I previously mentioned it in October of last year. So, they're decidedly out of the loop, but they do have a good write-up on it. I'll go into a few more details on ideas here.
How bad is the problem? Over the last two weeks we've had two client machines compromised, though in neither case was any privilege escalation done. Only regular user accounts were compromised. In one case the system is used for development of an open source project, and password authentication is allowed. A user selected a weak password. In another, it was a company server, and a user probably had a weak password.
I mentioned previously about moving your SSH daemon to a different port. This is effective for the current attacks, but easy for a determined remote attacker to track down, because SSH announces itself when you first connect:
guin:~$ telnet 127.0.0.1 22 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. SSH-2.0-OpenSSH_4.1 Protocol mismatch. Connection closed by foreign host. guin:~$
Of course, one thing you could do is set up a fake SSH server on one port and then use NAT to make a bunch of unused ports look like they have SSH running on them...
A better approach may be to set up a VPN and only allow SSH and other management access via the VPN. So, completely lock down SSH from access except via your VPN. Of course, if the VPN is down for any reason, you're not going to be able to use SSH. Some combination of a VPN with port-knocking to allow you to get in in an emergency may be the best option.
Another option that may be good as a workaround is to use a poorly documented iptables module named "hashlimit". The hashlimit module (run "iptables -m hashlimit --help" for more information on it) allows you to rate-limit traffic with unique limits based on source IP address (among other things). For example:
 guin:tummy# iptables -I INPUT -m tcp -p tcp --dport 22 -m state --state NEW -j REJECT  guin:tummy# iptables -I INPUT -m hashlimit -m tcp -p tcp --dport 22 --hashlimit 1/min --hashlimit-mode srcip --hashlimit-name ssh -m state --state NEW -j ACCEPT  guin:tummy# telnet 127.0.0.1 22 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. SSH-2.0-OpenSSH_4.1 Protocol mismatch. Connection closed by foreign host.  guin:tummy# telnet 127.0.0.1 22 Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused telnet: Unable to connect to remote host: Connection refused  guin:tummy# cat /proc/net/ipt_hashlimit/ssh 9 220.127.116.11:0->0.0.0.0:0 9600000 9600000 1920000 9 127.0.0.1:0->0.0.0.0:0 259392 9600000 1920000  guin:tummy#
In English, what we've done is:
Of course, the real solution is to have strong passwords, or even no passwords at all. I highly recommend using SSH public/private key authentication over password authentication. There are many benefits to this approach:
SSH public key authentication is a great thing, but you do have to then be very careful about where that encrypted key is stored, and who has access to the system where it is stored. If you just use regular ssh-agent authentication, it will keep an unencrypted copy of your key in memory, which may allow another local user to gain access to it. Using a smart-card can prevent this attack.
I said it before: Some people take all the fun out of SSH.comments powered by Disqus