# Brute Force SSH Attack...  How to stop it...

## bfloeagle

I noticed in /var/log/messages a bunch of people have been trying to brute force login to my box via SSH.  The box is online and open to the Internet via SSH (it's how I connect) but I thought it was a little more proactive at detecting intrusions than I thought...

```
...just a snippet, thousands more grouped in relative short time periods from similar ip's, probably a cable/dsl modem getting a new IP each time...

Jun 19 15:14:02 ds9 sshd[16052]: Invalid user samba from 220.227.XXX.XXX

Jun 19 15:14:04 ds9 sshd[16064]: Invalid user tomcat from 220.227.XXX.XXX

Jun 19 15:14:07 ds9 sshd[16068]: Invalid user webadmin from 220.227.XXX.XXX

Jun 19 15:14:11 ds9 sshd[16072]: Invalid user spam from 220.227.XXX.XXX

Jun 19 15:14:14 ds9 sshd[16076]: Invalid user virus from 220.227.XXX.XXX

Jun 19 15:14:17 ds9 sshd[16080]: Invalid user cyrus from 220.227.XXX.XXX

Jun 19 15:14:21 ds9 sshd[16084]: Invalid user oracle from 220.227.XXX.XXX

Jun 19 15:14:24 ds9 sshd[16088]: Invalid user michael from 220.227.XXX.XXX

Jun 19 15:14:28 ds9 sshd[16092]: Invalid user ftp from 220.227.XXX.XXX

Jun 19 15:14:31 ds9 sshd[16096]: Invalid user test from 220.227.XXX.XXX

Jun 19 15:14:33 ds9 sshd[16100]: Invalid user webmaster from 220.227.XXX.XXX

Jun 19 15:14:39 ds9 sshd[16108]: Invalid user postfix from 220.227.XXX.XXX

Jun 19 15:14:42 ds9 sshd[16112]: Invalid user postgres from 220.227.XXX.XXX

Jun 19 15:14:45 ds9 sshd[16116]: Invalid user paul from 220.227.XXX.XXX

Jun 19 15:14:52 ds9 sshd[16124]: Invalid user guest from 220.227.XXX.XXX

Jun 19 15:14:56 ds9 sshd[16128]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:14:59 ds9 sshd[16132]: Invalid user linux from 220.227.XXX.XXX

Jun 19 15:15:02 ds9 sshd[16136]: Invalid user user from 220.227.XXX.XXX

Jun 19 15:15:06 ds9 sshd[16140]: Invalid user david from 220.227.XXX.XXX

Jun 19 15:15:10 ds9 sshd[16144]: Invalid user web from 220.227.XXX.XXX

Jun 19 15:15:13 ds9 sshd[16148]: Invalid user apache from 220.227.XXX.XXX

Jun 19 15:15:16 ds9 sshd[16152]: Invalid user pgsql from 220.227.XXX.XXX

Jun 19 15:15:18 ds9 sshd[16156]: Invalid user mysql from 220.227.XXX.XXX

Jun 19 15:15:21 ds9 sshd[16160]: Invalid user info from 220.227.XXX.XXX

Jun 19 15:15:24 ds9 sshd[16164]: Invalid user tony from 220.227.XXX.XXX

Jun 19 15:15:27 ds9 sshd[16168]: Invalid user core from 220.227.XXX.XXX

Jun 19 15:15:30 ds9 sshd[16172]: Invalid user newsletter from 220.227.XXX.XXX

Jun 19 15:15:36 ds9 sshd[16176]: Invalid user named from 220.227.XXX.XXX

Jun 19 15:15:39 ds9 sshd[16180]: Invalid user visitor from 220.227.XXX.XXX

Jun 19 15:15:41 ds9 sshd[16184]: Invalid user ftpuser from 220.227.XXX.XXX

Jun 19 15:15:44 ds9 sshd[16188]: Invalid user username from 220.227.XXX.XXX

Jun 19 15:15:47 ds9 sshd[16192]: Invalid user administrator from 220.227.XXX.XXX

Jun 19 15:15:50 ds9 sshd[16196]: Invalid user library from 220.227.XXX.XXX

Jun 19 15:15:53 ds9 sshd[16200]: Invalid user test from 220.227.XXX.XXX

Jun 19 15:16:01 ds9 sshd[16212]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:16:04 ds9 sshd[16216]: Invalid user guest from 220.227.XXX.XXX

Jun 19 15:16:11 ds9 sshd[16220]: Invalid user master from 220.227.XXX.XXX

Jun 19 15:16:35 ds9 sshd[16244]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:16:38 ds9 sshd[16248]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:16:40 ds9 sshd[16252]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:16:44 ds9 sshd[16256]: Invalid user admin from 220.227.XXX.XXX

Jun 19 15:16:52 ds9 sshd[16268]: Invalid user test from 220.227.XXX.XXX

Jun 19 15:16:56 ds9 sshd[16272]: Invalid user test from 220.227.XXX.XXX

Jun 19 15:16:59 ds9 sshd[16276]: Invalid user webmaster from 220.227.XXX.XXX

Jun 19 15:17:03 ds9 sshd[16280]: Invalid user username from 220.227.XXX.XXX

Jun 19 15:17:09 ds9 sshd[16284]: Invalid user user from 220.227.XXX.XXX
```

Since I connect from a bunch of different places, I can't really lock down SSH to only allow connections from particular hosts.  I realize that a box on the Internet is prone to these type of attempts but how to I stop them after the same host tries to authenticate and fails after a few times???  How do I stop an IP from making connections to my box after a few failed or invalid logon attempts?  Can SSH do it or is there another intrusion detection system I can install?

Thanks!

Andy

----------

## Hu

The package net-analyzer/fail2ban is often recommended for this purpose.

----------

## papafox

Try app-admin/denyhosts.  It is specifically designed to handle SSH brute force attacks.  As attacks are detected, the originating IP address is posted to a shared database.  This lets denyhosts refuse the SSH connection before the attack has a chance to develop.  IP's are un-banned after a configurable timeout.

It also has the effect of making SSH attacks less profitable.  If enough site have denyhosts installed, attackers will find that their IP becomes useless after a short period of time.  The reward-to-effort ratio will be reduced considerably.

----------

## Dralnu

Problem being that banning an IP is a pretty lousy way to ban someone. Hell, unless you have a static IP, all you have to do is power off/on your modem, grab a new IP, and keep going. Or spoof a new one, though that CAN be ignored and the real IP found...

----------

## papafox

 *Dralnu wrote:*   

> Problem being that banning an IP is a pretty lousy way to ban someone. Hell, unless you have a static IP, all you have to do is power off/on your modem, grab a new IP, and keep going. Or spoof a new one, though that CAN be ignored and the real IP found...

 

What you say is true ... but not applicable in this case.

The way these attacks work is that someone writes a script which does a port scan and builds a list of IP's with a SSH listener.  Then it works through the list repeatedly connecting and trying a different userid/password combination.  Once the script manages a successful login, it copies the script, plus a backdoor IRC daemon to the user account.  The backdoor reports success to a webserver somewhere and starts listening for commands using IRC (which typically tell it to send spam or run DOS attacks).  The attack script then starts running on the new machine  to try and spread to other machines on the local LAN.  These scripts are typically written in perl (since most machines which have SSH would have perl as well).  Also, note these scripts are running on ordinary user accounts, they don't need root.

So, since they are automated scripts rather than real people, the IP address will not (probably) be changing and banning the IP address is a successful way of defeating these attacks.  

The app-admin/denyhosts package has three functions - it detects attacks by monitoring the log for multiple SSH login failures; it regularly replicates a shared database of known attackers; and it maintains the /etc/hosts.deny config file to allow SSH to pre-emptively deny connections from attackers.   The entries in /etc/deny.hosts can be configured to block all connections from the attacking IP address or just those to SSH.  If you are running Shorewall, there is an interface to add the attacker to the Shorewall block list so that all packets (not just TCP connections) are dropped.

While blocking an IP address not seem to be workable, in this case it is an actually extremely effective solution.  The key feature is the ability to deny access to the attacker before they begin the attack.

----------

## Dralnu

The basic "You can't stop them all, just the script-kiddies" idea?

I understand your point, but I wanted to make sure that was understood.

----------

## bunder

 *papafox wrote:*   

> While blocking an IP address not seem to be workable, in this case it is an actually extremely effective solution.  The key feature is the ability to deny access to the attacker before they begin the attack.

 

that's why i outright cidr ban asian countries, and hosting providers... tired of dns/ftp/web servers being hijacked and used to ssh/ftp/mail "spam".   :Rolling Eyes:   :Evil or Very Mad: 

haven't had to do it very often to north american networks, but verizon has pissed me off on a couple occasions, and so has level3.   :Shocked: 

you would think with how isp's treat their end users, having to sign a non-hack/spam eula, that they would do something about these attacks that spawn from their network...  i'd just love to see serverpronto or ev1servers get their internet access revoked due to their spammyness.

----------

## Cyker

That sort of stuff is just to cover the ISP's ass, not protect us from their users.

I used to do reverse traces with a full nmap workup on IP's that were trying to break into my box, but I never got a single reply or anything done about it from the ISP.

Now I go with the general consensus on slashdot, which is just to ignore them.

I wrote my own set of rules using the SEC daemon, which works similarly to denyhosts (Except I can read it and modify it myself more easily).

That seems to have done the trick, although since I switched ISPs and now have a static address I've noticed some more sophisticated attacks recently  :Sad: 

To counter it, in addition to the existing rules ("Did not recieve identification"=instant ban, 3-login fails=instant ban) I put in a random 2-10s delay with each login attempt.

I also want to set up some sort of port-knocking thing, but I need a router (And client!)  that supports it first...  :Sad: 

----------

## pdr

I changed my port from 22 and get a hack attempt maybe once a year. This was actually a side benefit; had to use a different port to be able to log in from work through their firewall..

----------

## bunder

 *pdr wrote:*   

> I changed my port from 22 and get a hack attempt maybe once a year. This was actually a side benefit; had to use a different port to be able to log in from work through their firewall..

 

that is always an option, but i don't consider that a proper option as port 22 was designated for ssh.  why should i have to change my ports just to prevent network spam?  these people shouldn't be letting their boxes get hijacked in the first place.  like seriously, how hard is it to keep a web server secure?  i've run mail/web/ftp/ssh and stuff for years and never had an intrusion.  maybe i'm lucky, or maybe i'm actually keeping my boxes up to date.  i still place all the blame on the hosting companies for not securing their networks.

----------

## pdr

I don't get philosophical when it comes to administering my server or workstation.

----------

## bunder

i just don't see why end-users get the shaft while big companies and foreign networks can violate the rest of the internet.  i demand equality.   :Razz: 

----------

## richmastaplus

Will somebody tell me how to block all ips except north america, if not how do i just block asia.  As that is where I'm getting attacks from.

----------

## Dralnu

I'd block Asia, Africa, parts of eastern Europe, and more then likely the pacific islands...

----------

## jlh

See also this thread about the same topic.

You could try to implement some enable-ssh-on-demand trickery, I've seen this somewhere on the net once.  The basic idea is that SSH is banned for everyone.  To unblock it, an IP needs to make a dummy connection to a different port, which will unblock SSH for this IP only for a while (or permanently, at your wish).

I don't think banning by location is a great idea, as attacks come from everywhere anyway (often from already compromised systems, which really can be anywhere in the world).  I'd suggest to ban anyone that tries wrong usernames (or maybe anyone that makes more than 5 connections in a row), that seems the most effective to me.  I'm running a honeypot and the almost 39'000 SSH connections that I got in the last 3 weeks all came from the same 79 different IPs.  That means you really don't want to ban almost all the world, but you want to ban the bad guys as they appear, and they're easy to spot.

----------

## Hu

 *jlh wrote:*   

> You could try to implement some enable-ssh-on-demand trickery, I've seen this somewhere on the net once.  The basic idea is that SSH is banned for everyone.  To unblock it, an IP needs to make a dummy connection to a different port, which will unblock SSH for this IP only for a while (or permanently, at your wish).

 

For the benefit of future readers: this is often referred to as "port knocking."  From what I have read, some people have come up with very elaborate knocking schemes based on timing, ordering, and even the content of the packets sent to the knocked ports.  For example, must receive a SYN to 13529, then a data packet with string "foo" to port 25089 (despite no actual connection or service on that port), etc.  Beware that as your scheme gets more elaborate, you increase the difficulty of performing the knock successfully, as well as increasing the risk that some highly stateful firewall may drop some of your knock packets for being "invalid" according to its state tracking tables.

There is a package in Portage called net-misc/knock, which is described as "A simple port-knocking daemon."

----------

## Dralnu

Let me guess, you could run this all the way up to changing the knock some to setup an encrypted contection with a specific key?

----------

## Hu

 *Dralnu wrote:*   

> Let me guess, you could run this all the way up to changing the knock some to setup an encrypted contection with a specific key?

 

Probably, but that sounds overly complex.  I would go with using a port knock to protect a VPN daemon, then establish a VPN to get the encryption.  :Wink: 

----------

## Dralnu

 *Hu wrote:*   

>  *Dralnu wrote:*   Let me guess, you could run this all the way up to changing the knock some to setup an encrypted contection with a specific key? 
> 
> Probably, but that sounds overly complex.  I would go with using a port knock to protect a VPN daemon, then establish a VPN to get the encryption. 

 

So you wouldn't want to try and make an electronic Enigma machine? Personally, I'd look into setting up a formula to the knocks, otherwise someone could still sniff out your little port drum solo, and mimic it to get access...

----------

## think4urs11

 *Dralnu wrote:*   

>  *Hu wrote:*    *Dralnu wrote:*   Let me guess, you could run this all the way up to changing the knock some to setup an encrypted contection with a specific key? Probably, but that sounds overly complex.  I would go with using a port knock to protect a VPN daemon, then establish a VPN to get the encryption.  So you wouldn't want to try and make an electronic Enigma machine? Personally, I'd look into setting up a formula to the knocks, otherwise someone could still sniff out your little port drum solo, and mimic it to get access...

 

A bit paranoid, isn't it? To make that happen $attacker would need to be able to sniff either your access line at home (not impossible but at least non-trivial) or the location you're knocking from (pretty impossible as it could be theoretically everywhere).

Anyways, paranoid souls could hack something with OTP.

a) pre-generate yourself a list of one-time passwords to take with you

b) implement a knock daemon which uses that list, of course every OTP only once

each of the six 2-4 letter words are interpreted as a hex-value for the port which needs to be knocked to. With each successful knock-sequence the knock-daemon drops that from the list and waits for the next one.

When the knock is sucessful the ssh (or openvpn) daemon are started and configured to allow the knockers ip only for e.g. 2 minutes.

If no sucessful connect is established with that within those 2 minutes the daemon gets killed again and if you like the ip dropped with iptables.

With that $attacker would need to guess the correct knock sequence first (practically impossible) plus then needs to hack the (certificate or public key _only_) openvpn/ssh within the next two minutes (practically impossible) and (s)he has only one try per IP (ok, every good attacker has a big zombie network for this but hey ...) and you'd know that an attack happened afterwards (unless (s)he's clever enough to re-setup the knock-daemon [not too hard] with the correct next knock sequence [pretty much impossible as s(h)e need to know the actual pointer to the list the knock daemon points at i.e. (s)he'd need to find that in a memory dump] - of course that should be mad impossible with utilizing selinux and alike).

/paranoia off   :Rolling Eyes: 

----------

## bfloeagle

...  :Shocked: 

Talk about unleashing the floodgates...    :Razz:   Thanks for the tips everyone.  

...now get back to the discussion...   :Wink: 

----------

## Dralnu

 *Think4UrS11 wrote:*   

>  *Dralnu wrote:*    *Hu wrote:*    *Dralnu wrote:*   Let me guess, you could run this all the way up to changing the knock some to setup an encrypted contection with a specific key? Probably, but that sounds overly complex.  I would go with using a port knock to protect a VPN daemon, then establish a VPN to get the encryption.  So you wouldn't want to try and make an electronic Enigma machine? Personally, I'd look into setting up a formula to the knocks, otherwise someone could still sniff out your little port drum solo, and mimic it to get access... 
> 
> A bit paranoid, isn't it? To make that happen $attacker would need to be able to sniff either your access line at home (not impossible but at least non-trivial) or the location you're knocking from (pretty impossible as it could be theoretically everywhere).
> 
> Anyways, paranoid souls could hack something with OTP.
> ...

 

Why 2 minutes? Make it 30 seconds, and instead of using six 2-4 letter words, maybe require six 24-letter words (someone here have a medical dictionary handy?) translated into binary Latin and encrypted with 512-bit encryption, just to make it a little bit harder.

----------

## bfloeagle

 *Dralnu wrote:*   

> Why 2 minutes? Make it 30 seconds, and instead of using six 2-4 letter words, maybe require six 24-letter words (someone here have a medical dictionary handy?) translated into binary Latin and encrypted with 512-bit encryption, just to make it a little bit harder.

 

Social engineering sounds easier at this point...  I am your long lost third cousin on your father's mother's aunt's side second removed anyway...    :Razz: 

----------

## Dralnu

Good idea - use a researchable family tree to figure out which ports to knock...

----------

## timeBandit

 *Dralnu wrote:*   

> Good idea - use a researchable family tree to figure out which ports to knock...

 

...and Bob's your uncle.   :Laughing: 

/me ducks

----------

## v3rn60

Hi I used a program called daemonshield to block brute force attacks it bans the ip if they get the password is wrong 3 times in a row, it's very configureable

paul

----------

## krakadikt5k

My rather bad idea as a solution is to setup a dummy sshd server on port 2222 (above 1024) to be run as nobody with absolutely no successfull logins. and make a script checking for failed login attempts and after 5+ automaticaly forwarding conenctions to port 22 -> port 2222. 

The two versions of sshd share most of the same files so it'll be hard for the attackers to know the difference but I'm having trouble finding a to make the login failures loot the same on the fake sshd server, same quiet failure that the normal sshd server gives them. The config setting 

```
AllowUsers nobody
```

 causes an "access denied" message. 

I think I probably need to make a pam module for my fake sshd server sshd-fake (a symlink to sshd). Anyone know how to set sshd or pam up so it will never allow a login but fail silently like the normal sshd?

-dan

----------

## depontius

I only expect to ssh into my home cluster from certain locations, that happen to have static IPs.  I use tcp-wrappers and firewalling to enforce that policy.  I realize it isn't the general case, but it works for me, it's minimal, and it's simple.

----------

## lnthai2002

just want to tag this post for latter reference

----------

## eccerr0r

I get these ssh connections from all over the world.  Unfortunately moving the port means I can't connect from work, it's the only port I can use.

The top three offenders by far are:

China

USA

Korea

and the list of attacking machines grows daily  :Sad: 

----------

## peaceful

Is there a simple way to make it so that if a certain number of failed ssh login attempts occur, then that IP address is blocked from trying to login through ssh for a specified amount of time?

I couldn't find anything in the ssh_config and sshd_config man pages.  I found an "sshdfilter" package on the web that looks like it's pretty close to that, but it's not in portage.

Any suggestions would be appreciated.

----------

## matze_na

i think what you want to take a look at is fail2ban.

----------

## peaceful

That's perfect!  I set it up, and it works.

I had to create an /etc/fail2ban/jail.local file and enable the ssh jail and fix the path to /var/log/messages, and create an /etc/fail2ban/filter.d/sshd.local file and add a new regex for it to match the login failure lines.  And then it started working like a charm.

Thanks!

----------

## nixnut

merged above three posts here.

----------

## Simba7

I just laugh at them when someone tries. They're usually dictionary attacks and the basic login names. I get them on my FTP and Telnet servers, too.

I get more attempts to get a Windows IIS exploit to run on an Apache box then login attempts. The only thing that gets bigger is my log file which is crushed by bzip2 anyway by the end of the week.

----------

## dc46and2

I'm surprised that the OpenSSH daemon itself doesn't offer this functionality.  It seems like it would be easier to implement a simple "three strikes and we ignore you" option in sshd itself, instead of trying to deduce a problem by scanning log files.  Too bad I don't know much about how to write these programs.

----------

## jcat

I use the "blockhosts" scripts to ban IP's of a particular number of failed auth attempts.  It bans the IP using tcpd wrappers and iptables, it can also setup null routes..  I have it running every 5 mins, and it emails me once a day wiht a list of failed login attemps and blocked IP's.

Blockhosts is good because you can configure it to block unwanted connections to other services like ftp, www, etc..

One thing that shouldn't be overlooked is the basic configuration of sshd.  Make sure you set it up to only allow protocol version 2, disallow root logins, and only allow logins from specified users (if you're the only one that logs in via ssh, just allow yourself).

And, these are brute force dictionary attacks people, so make sure you're passwords are strong and secure and you'll be fine!   :Very Happy: 

Cheers,

jcat

----------

## marwooj

try fwknop - Single Packet Authorization

http://www.cipherdyne.org/fwknop/

----------

## DevSolar

 *jcat wrote:*   

> ...these are brute force dictionary attacks people, so make sure you're passwords are strong and secure and you'll be fine!

 

I use public key authentication only, enforced in /etc/ssh/sshd_config by a simple:

```

ChallengeResponseAuthentication no

# Add this while you are at it

PermitRootLogin no

```

They can dictionary-brute-force 2048bit keys as long as they like. But denyhosts sounds like a good trick to keep log file noise down. Thanks!  :Wink: 

----------

## lesourbe

I've not red thoroughly every post in here, but it seems nobody mentioned the portknocking option.

----------

## jcat

 *lesourbe wrote:*   

> I've not red thoroughly every post in here, but it seems nobody mentioned the portknocking option.

 

Hehehe, clearly you haven't read every post thoroughly!   :Laughing: 

Cheers,

jcat

----------

## coolsnowmen

 *bunder wrote:*   

> 
> 
> that's why i outright cidr ban asian countries, and hosting providers... tired of dns/ftp/web servers being hijacked and used to ssh/ftp/mail "spam".   
> 
> 

 

I very much would like to do this, how to? PlEASE!

my log files would be soooooo much smaller   :Very Happy: 

----------

## piwacet

 *marwooj wrote:*   

> try fwknop - Single Packet Authorization
> 
> http://www.cipherdyne.org/fwknop/

 

Yeah I got this set up - works well.

----------

## Shnoodle

 *krakadikt5k wrote:*   

> My rather bad idea as a solution is to setup a dummy sshd server on port 2222 (above 1024) to be run as nobody with absolutely no successfull logins. and make a script checking for failed login attempts and after 5+ automaticaly forwarding conenctions to port 22 -> port 2222. 
> 
> The two versions of sshd share most of the same files so it'll be hard for the attackers to know the difference but I'm having trouble finding a to make the login failures loot the same on the fake sshd server, same quiet failure that the normal sshd server gives them. The config setting 
> 
> ```
> ...

 

I think you're giving attackers a real gift with this RYO fake-ssh script, even run with 'nobody' perms.

The safest methodology isn't to add more services/scripts, but to reduce the risks already there. The best way to harden the single point of attack by obfuscation and configuration. I would change the default sshd configuration, there is copious information on what to do there. I would use the opie PAM, then I'd configure PAM! I'd have my keychain on my irl keychain in an encrypted flash stick. I'd tweak the firewalls and IDS to log and drop anything that breaks the baseline. Most of these suggestions are elaborated elsewhere in this thread, hope I have guided you from failure.

----------

## lesourbe

 *jcat wrote:*   

>  *lesourbe wrote:*   I've not red thoroughly every post in here, but it seems nobody mentioned the portknocking option. 
> 
> Hehehe, clearly you haven't read every post thoroughly!  
> 
> Cheers,
> ...

 

Ok, my apologies then   :Wink: 

----------

## Robert S

I use the iptables recent module:

```

# SSH protection table

# see http://www.stanford.edu/~fenn/linux/dhclient-exit-hooks

IPTABLES=/sbin/iptables

  $IPTABLES -N SSH

  $IPTABLES -F SSH

  $IPTABLES -A SSH -m recent --name SSH --set --rsource

  $IPTABLES -A SSH -m recent ! --rcheck --seconds 60 --hitcount 3 --name SSH --rsource -j ACCEPT

  $IPTABLES -A SSH -j ULOG --ulog-prefix="Bad SSH"

  $IPTABLES -A SSH -j DROP

  $IPTABLES -A INPUT -p tcp -i $WAN --dport ssh -m state --state NEW -j SSH

```

app-admin/sshguard, which is in portage, also works well.

----------

