51

What tool or technique do you use to prevent brute force attacks against your ssh port. I noticed in my Security logs, that I have millions of attempts to login as various users through ssh.

This is on a FreeBSD box, but I imagine it would be applicable anywhere.

grieve
  • 1,517
  • 3
  • 17
  • 18

14 Answers14

43

I use fail2ban which will lock an IP out after several failed attempts for a configurable amount of time.

Combine this with password strength testing (using john (John the Ripper)) to ensure brute-force attacks will not succeed.

Brent
  • 22,219
  • 19
  • 68
  • 102
  • 4
    Fail2ban is excellent. It was simple to extend it to monitor /var/log/maillog and get it to ban persistent spammers from hitting my mail server – Dave Cheney May 05 '09 at 15:50
  • Fail2ban can be combined with an iptables chain that sends tcp traffic to the `TARPIT` target, if you are feeling nasty (from xtables-addons). – Tobu Jul 02 '10 at 19:19
27

Here's a good post on that subject by Rainer Wichmann.

It explains pros and cons on theses methods to do it :

  • Strong passwords
  • RSA authentication
  • Using 'iptables' to block the attack
  • Using the sshd log to block attacks
  • Using tcp_wrappers to block attacks
  • Port knocking
paulgreg
  • 4,094
  • 6
  • 31
  • 32
24

Ons small thing you can do is use something like DenyHosts:

http://denyhosts.sourceforge.net/

It uses the built-in hosts.allow/hosts.deny to block out SSH abusers.

hernan43
  • 876
  • 8
  • 6
16
Chris Ballance
  • 304
  • 1
  • 7
  • 20
15

One of the easiest ways to avoid these attacks is to change the port that sshd listens on

trent
  • 3,094
  • 18
  • 17
  • 1
    If, of course, you system can stand it. – C. Ross May 04 '09 at 23:23
  • 13
    Security through obscurity, effective every single time. – Chris Ballance May 05 '09 at 00:59
  • 1
    I wouldn't mind changing the port all that much, but I have learned that most firewalls (other than my own) tend to lock down all ports other than the common ones (80,22, 443, etc). If I am behind those firewalls I cannot get to my home server on that nonstandard port. For me that is a no go. – grieve May 27 '09 at 20:59
  • @grieve then change our firewall to let that port out? – Amandasaurus Aug 05 '09 at 13:32
  • @Roy I am talking about firewalls other than the ones I own. For example if I want to ssh into my home machine from Starbucks, their firewall blocks the outgoing port. I cannot change that. (I just used Starbucks as an example. I have no idea what ports they actually block or not). – grieve Mar 06 '12 at 21:16
12

In addition to the other good suggestions, one really easy thing to do is rate-limit incoming connections. Limit to 3 connections per minute per IP:

iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
sherbang
  • 361
  • 3
  • 6
  • I might be misunderstanding something, but many mainstream browsers connect between 4-6 connections at a time - even though the HTTP standard sets it at 2. – Joshua Enfield Jul 02 '10 at 19:51
  • 1
    Yes, that would be a problem if you were trying to rate-limit port 80. You're not connecting to ssh with your web-browser, and ssh sessions are long-lived sessions that maintain state, not short-lived stateless sessions like http. Parallelizing ssh sessions like that doesn't make sense. That's not to say that there isn't some niche use of ssh that this would break, but it's rare. – sherbang Aug 25 '11 at 12:03
  • This solution is not so good if, like me, you are serving Subversion via ssh. A single SVN query can make a great number of connections in quick succession. If providing that service, you could either use a second sshd service on another port, or whitelist known IPs. I am thinking of using fail2ban or sshdfilter to catch obvious attacks the first time around, without punishing my legitimate users. – paddy Jan 06 '13 at 21:52
  • good to know this option too... – ZEE May 14 '18 at 19:50
12

As Chris points out, use encryption keys instead of passwords.

Add to that:

  • use a whitelist where possible.

How many people or locations (with floating public IPs) do you really need accessing your public ssh connections ?

Depending on the number of public ssh hosts you are maintaining and whether you can narrow down your general connection criteria's then it may be a simpler, maintanable configuration to limit access to a few external hosts.

If this works for you, it can really simplify your administration overhead.

samt
  • 713
  • 4
  • 10
  • 2
    Whitelisting is hugely important if you are doing any kind of blacklisting unless you want to get locked out. – Ryaner May 05 '09 at 07:42
  • 3
    +1 for having the absolute best answer. Those two things are the only reasonable steps, and they are very effective indeed. Either alone is worthwhile, and both together more so. Boo on the other answers advocating security through obscurity! – dwc May 23 '09 at 17:44
6

Use the "AllowUsers" option in sshd_config to ensure only a small set of users can log in at all. All others will get rejected, even if their username and password are correct.

You can even restrict users to logins from a particular host.

e.g.,

AllowUsers user1 user2@host.example.com

This will reduce the search-space and avoid those old users which have accidentally been left laying around or enabled (although these of course should be disabled anyway, this is an easy way to stop them being used for an SSH-based entry).

This doesn't entirely stop the brute-force attacks, but helps reduce the risk.

David Gardner
  • 1,499
  • 2
  • 13
  • 25
3

Use something like that with PF:

table <ssh-brute> persist
block in quick log from label ssh_brute
pass in on $ext_if proto tcp to ($ext_if) port ssh modulate state \
(max-src-conn-rate 3/10, overload flush global)

2

Further to sherbang's rate-limiting suggestion, the length of the delay is important. By increasing the delay between groups of 3 login attempts from 2 minutes to 20 minutes, the number of different IP addresses that made more than three attempts to login dropped, comparing two week-long periods on one machine of mine, from 44 attempts to 3. None of those three addresses kept trying for longer than 11 hours.

Very anecdotal, but auth.log became a whole lot more readable for me...

Charles Stewart
  • 650
  • 6
  • 19
2

Port-knocking is a pretty solid way to keep this sort of thing out. Slightly fiddly, sometimes annoying, but it definitely makes the issue go away.

Luke
  • 692
  • 4
  • 6
  • I have tried this and users find it annoying. If it's only one or two people, this could be a good option, and would nearly eliminate brute-force attacks – Brent May 04 '09 at 17:54
2

Context is important, but I'd recommend something like so:

  • Since you're using FreeBSD, consider running the PF firewall and using its solid connection rate-limiting features. This will allow you to send the brute forcers to a black list if they connect on a frequent basis
  • If this box must be accessed from the outside world, consider using a PF rdr rule to not allow traffic to port 22, but to redirect some obscure port to it. Meaning, you have to connect to port 9122 instead of 22. It is obscure, but it keeps the knockers away
  • consider moving to key-based authentication only, making dictionary attacks useless
Michael Gorsuch
  • 2,358
  • 1
  • 21
  • 24
1

install OSSEC. not only it monitors for repeated logins, it will enter a temporary block with iptables for the offending ip. And at the end it will send you a report stating the details. it logs everything, which is nice. Somone once tried over 8000 login names to log in with. i parsed the logs and got a nice user list out of deal ;)

Marcin
  • 2,281
  • 1
  • 16
  • 14
1

I just don't care about it. Let them belt away at the port, they're not going to brute-force a key.

womble
  • 95,029
  • 29
  • 173
  • 228
  • -1 Ever heard of DoS attacks? – Chris Ballance May 05 '09 at 15:38
  • 8
    Yeah, because SSH is the only service susceptible to brute force attacks. If you've got a port open to the Internet, it can be used to hammer your machine into oblivion. You probably put your HTTP server on weird ports too, and behind port knocking, to "avoid DoS attacks"... – womble May 06 '09 at 00:07