Repository: EasyEngine/easyengine

Issue #118: Improve the EE security with adding Fail2Ban
Created: 2014-02-08T17:41:41Z
I was wondering, how possible would be to focus on the security of the LEMP server of EasyEngine by adding Fail2Ban, in the package.
The idea came to me by reading this article http://kovshenin.com/2014/fail2ban-wordpress-nginx/
I am not a security expert. I just think that if EasyEngine focuses more to the security side, it would be a top-notch tool for easy wordpress deployment.

Duplicate issue #152: Fail2ban
Created: 2014-03-14T02:24:57Z
Add fail2ban as an optionnal intall (system), install (website)
I guess it should be ee.conf based like:

fail2ban_intall = true (for this we need install fail2ban config at system installation)
default_fail2ban_to_all_websites = true

Then per website:

adding and activating the 2 available plugins wp-fail2ban stop-user-enumeration to plugin install list in ee.conf (there's a cp trick to make them work as indicated by plugins doc but we should be already done at fail2ban install)

We may also add a command line arg like --with-fail2ban? Dunno...
Here is my actual fail2ban config interesting parts:
First the two should be copied files:
cat /etc/fail2ban/filters.d/wordpress.conf
# Fail2Ban configuration file
#
# Author: Charles Lecklider
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf


[Definition]

_daemon = wordpress

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
            ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
            ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =


cat /etc/fail2ban/filters.d/wordpress-user-enum.conf
[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf


[Definition]

_daemon = wordpressuser

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = ^%(__prefix_line)sAttempted user enumeration from <HOST>$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

==== And of course my jail.local:
cat /etc/fail2ban/jail.local
[DEFAULT]

# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8 example.org 81.289.187.33
bantime  = 600
maxretry = 3

# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto".
# yoh: For some reason Debian shipped python-gamin didn't work as expected
#      This issue left ToDo, so polling is default backend for now
backend = polling

destemail = example@gmail.com

# ACTIONS

banaction = iptables-multiport

# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
mta = sendmail

# Default protocol
protocol = tcp

# Specify chain where jumps would need to be added in iptables-* actions
chain = INPUT

# Action shortcuts. To be used to define action parameter

# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
              %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
               %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

# Choose default action.  To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_mwl)s

# in /etc/fail2ban/jail.local.

[ssh]

enabled  = true
port     = 22
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3

[ssh-ddos]

enabled  = true
port     = 22
filter   = sshd-ddos
logpath  = /var/log/auth.log
maxretry = 5

# HTTP servers

[wordpress]
enabled = true
port    = http,https
filter = wordpress
logpath = /var/log/auth.log

[wordpress-userenum]
enabled = true
port    = http,https
filter  = wordpress-userenum
logpath = /var/log/messages
maxretry = 1
findtime = 600
bantime = 2500000

[nginx-auth]

enabled = true
port = http,https
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/nginx/*error.log
bantime = 3600 # 1 heure
maxretry = 3

[nginx-login]

enabled = true
port = http,https
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port="http,https"]
logpath = /var/log/nginx/*access.log
bantime = 1600
maxretry = 5

[nginx-badbots]

enabled  = true
port = http,https
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
logpath = /var/log/nginx/*access.log
bantime = 86400 # 1 day
maxretry = 1

[nginx-noscript]

enabled = false
port = http,https
action = iptables-multiport[name=NoScript, port="http,https"]
filter = nginx-noscript
logpath = /var/log/nginx/*access.log
maxretry = 6
bantime  = 86400 # 1 day

[nginx-badrequests]

enabled = true
filter = nginx-badrequests
port = http,https
logpath = /var/log/nginx/*access.log
maxretry = 3
findtime = 8640
bantime = 2592000
# Mail servers

[postfix]

enabled  = true
port     = smtp,ssmtp
filter   = postfix
logpath  = /var/log/mail.log

[postfix-connection]
enabled  = true
filter   = postfix-connection
logpath  = /var/log/mail.log
maxretry = 5
port     = all

[couriersmtp]

enabled  = false
port     = smtp,ssmtp
filter   = couriersmtp
logpath  = /var/log/mail.log

# Mail servers authenticators: might be used for smtp,ftp,imap servers, so

[courierauth]

enabled  = false
port     = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter   = courierlogin
logpath  = /var/log/mail.log


[sasl]

enabled  = true
port     = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter   = sasl
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
logpath  = /var/log/mail.warn

[dovecot]

enabled = true
port    = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
filter  = dovecot
logpath = /var/log/mail.log

Of course I've modified some info with false data like email, ip etc...
As you can see the nginx-noscript isn't activated on my machine as I've never been able to make it work....
Then I will post other nginx-specific files in another comment...

Closing comment (2015-03-18T12:15:10Z): Related to #118