fpco / fpco-salt-formula

9 stars 3 forks source link

Add formula to protect SSH from bruteforce attempts #51

Closed ketzacoatl closed 9 years ago

ketzacoatl commented 9 years ago

Denyhosts or fail2ban, or UFW, protect SSH from too many failed connection/login attempts.

ketzacoatl commented 9 years ago

This is actually best accomplished with this existing formula for fail2ban https://github.com/saltstack-formulas/fail2ban-formula.

I've deployed this formula in the HMST Support network - see more details here: ADD LINK - and am happy with how it functions by default. We can monitor the log and change our use of the tool based on what we see in the logs and how this app affects us.

I tested fail2ban in the following ways.

bad ssh key

First, I repeatedly tried to login with the wrong SSH key. Fail2ban did not block me, even after many many attempts (6 is all that I'd need if fail2ban would block on this event).

In shell:

for i in {1..10}
do
  ssh jason@ec2-54-193-70-225.us-west-1.compute.amazonaws.com
done

non-existent users

Next, I tried to login as multiple users who did not exist. Fail2ban blocked me almost immediately, after the 6th attempt. I was blocked by IP, for 10 minutes. An existing SSH session, with root access, was blocked, and subsequently came back after the 10 minute ban ended. Here is how I tested this:

ᐅ \
for i in {1..10}
do
  for user in moe larry curly tux
  do
    ssh $user@ec2-54-193-70-225.us-west-1.compute.amazonaws.com
  done
done

On the client, the ban looked like:

for> done
Permission denied (publickey).
Permission denied (publickey).
Permission denied (publickey).
Permission denied (publickey).
Permission denied (publickey).
Permission denied (publickey).

^C

On the server, the ban/unban looked like:

# tail -f /var/log/fail2ban.log  /var/log/auth.log
==> /var/log/fail2ban.log <==
2015-04-04 19:48:54,775 fail2ban.jail   : INFO   Creating new jail 'ssh'
2015-04-04 19:48:54,787 fail2ban.jail   : INFO   Jail 'ssh' uses pyinotify
2015-04-04 19:48:54,797 fail2ban.jail   : INFO   Initiated 'pyinotify' backend
2015-04-04 19:48:54,798 fail2ban.filter : INFO   Added logfile = /var/log/auth.log
2015-04-04 19:48:54,799 fail2ban.filter : INFO   Set maxRetry = 6
2015-04-04 19:48:54,799 fail2ban.filter : INFO   Set findtime = 600
2015-04-04 19:48:54,799 fail2ban.actions: INFO   Set banTime = 600
2015-04-04 19:48:54,819 fail2ban.jail   : INFO   Jail 'ssh' started
2015-04-04 19:57:07,368 fail2ban.actions: WARNING [ssh] Ban 12.3.4
2015-04-04 20:07:08,027 fail2ban.actions: WARNING [ssh] Unban 1.2.3.4

Where IP 1.2.3.4 is my IP as seen by the host.

The above gives us default behaviour, I'll see what it's like to enable fail2ban's DDoS protection for SSH.

ketzacoatl commented 9 years ago

Well, I've enabled the DDoS protection, but fail2ban doesn't seem to react (by default) to a bad SSH key.. eg, if SSH forces pubkey for login, and doesn't allow password auth, there isn't enough log output emitted (from SSH) for fail2ban's default filters to flag an ip for a ban.

Either way, I've added the following pillar to enable the SSH DDoS filter:

fail2ban:
  lookup:
    config:
      destemail: jason@fpcomplete.com
    jails:
       ssh_ddos:
         action:
           - iptables[name=SSH, port=ssh, protocol=tcp]
         enabled: 'true'
         filter: sshd-ddos
         logpath: /var/log/auth.log
         maxretry: 6
         port: ssh

More example pillar can be found here: https://github.com/saltstack-formulas/fail2ban-formula/blob/master/pillar.example

This covers the original intention of this ticket. I'll create a new ticket to include fail2ban in the default host.