Tips : Improving Zimbra Mail Server Security with Fail2Ban

Fail2ban_logoZimbra mail server has it’s own anti spam based on SpamAssasin and anti virus addon based on ClamAV to block incoming and outgoing malicious. The default addon has a pretty good performance when configured properly, but if you want to increase the security of Zimbra mail server, fail2ban is an additional plugin to be considered.

What is Fail2Ban

Fail2ban is an intrusion prevention framework written in the Python programming language. It is able to run on POSIX systems that have an interface to a packet-control system or firewall installed locally (for example, iptables or TCP Wrapper).

Fail2ban operates by monitoring log files (e.g. /var/log/pwdfail, /var/log/auth.log, etc.) for selected entries and running scripts based on them. Most commonly this is used to block selected IP addresses that may belong to hosts that are trying to breach the system’s security. It can ban any host IP that makes too many login attempts or performs any other unwanted action within a time frame defined by the administrator.

Here is a guide to improve the security of Zimbra mail server by using Fail2Ban :

  1. Install Fail2Ban and IPtables. If you are using Minimal Server Appliance, both Fail2ban and IPtables has been successfully installed on the appliance. To install it manually, run the following command with root permission :
    zypper ar fail2ban
    zypper in fail2ban
  2. Create a new file /etc/fail2ban/filter.d/zimbra.conf. This file contains regular expression to parsing Zimbra log which will trigger the banned process if it happens several times in a specified time interval. Contents of/etc/fail2ban/filter.d/zimbra.conf :
    # Fail2Ban configuration file
    # Author:
    # $Revision: 1 $
    # 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 = \[ip=<HOST>;\] account - authentication failed for .* \(no such account\)$
                            \[ip=<HOST>;\] security - cmd=Auth; .* error=authentication failed for .*, invalid password;$
                            ;oip=<HOST>;.* security - cmd=Auth; .* protocol=soap; error=authentication failed for .* invalid password;$
                            \[oip=<HOST>;.* SoapEngine - handler exception: authentication failed for .*, account not found$
                            WARN .*;ip=<HOST>;ua=ZimbraWebClient .* security - cmd=AdminAuth; .* error=authentication failed for .*;$
                            NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: Recipient address rejected:
    # .*\[ip=<HOST>;\] .* - authentication failed for .* \(invalid password\)
    # Option:  ignoreregex
    # Notes.:  regex to ignore. If this regex matches, the line is ignored.
    # Values:  TEXT
    ignoreregex =
  3. Create/edit /etc/fail2ban/jail.conf with the following contents :
    # Fail2Ban configuration file
    # Author: Cyril Jaquier
    # $Revision: 747 $
    ## The DEFAULT allows a global definition of the options. They can be overridden
    # in each jail afterwards.
    # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
    # ban a host which matches an address in this list. Several addresses can be
    # defined using space separator.
    ignoreip =
    # "bantime" is the number of seconds that a host is banned.
    bantime = 600
    # A host is banned if it has generated "maxretry" during the last "findtime"
    # seconds.
    findtime = 600
    # "maxretry" is the number of failures before a host get banned.
    maxretry = 3
    # "backend" specifies the backend used to get files modification. Available
    # options are "gamin", "polling" and "auto". This option can be overridden in
    # each jail too (use "gamin" for a jail and "polling" for another).
    # gamin: requires Gamin (a file alteration monitor) to be installed. If Gamin
    # is not installed, Fail2ban will use polling.
    # polling: uses a polling algorithm which does not require external libraries.
    # auto: will choose Gamin if available and polling otherwise.
    backend = auto
    # This jail corresponds to the standard configuration in Fail2ban 0.6.
    # The mail-whois action send a notification e-mail with a whois request
    # in the body.
    enabled = false
    filter = sshd
    action = iptables[name=SSH, port=ssh, protocol=tcp]
    logpath = /var/log/messages
    maxretry = 5
    # This jail forces the backend to "polling".
    enabled = false
    filter = sasl
    backend = polling
    action = iptables[name=sasl, port=smtp, protocol=tcp]
    logpath = /var/log/zimbra.log
    # Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
    # used to avoid banning the user "myuser".
    enabled = false
    filter = sshd
    action = hostsdeny
    ignoreregex = for myuser from
    logpath = /var/log/messages
    # This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip"
    # option is overridden in this jail. Moreover, the action "mail-whois" defines
    # the variable "name" which contains a comma using "". The characters '' are
    # valid too.
    enabled = true
    filter = zimbra
    action = iptables-allports[name=zimbra-account]
    logpath = /opt/zimbra/log/mailbox.log
    bantime = 600
    maxretry = 5
    enabled = true
    filter = zimbra
    action = iptables-allports[name=zimbra-audit]
    logpath = /opt/zimbra/log/audit.log
    bantime = 600
    maxretry = 5
    enabled = true
    filter = zimbra
    action = iptables-allports[name=zimbra-recipient]
    logpath = /var/log/zimbra.log
    #findtime = 604800
    bantime = 172800
    maxretry = 5
    enabled = true
    filter = postfix
    action = iptables-multiport[name=postfix, port=smtp, protocol=tcp]
    logpath = /var/log/zimbra.log
    bantime = -1
    maxretry = 5
    #enabled = true
    #port = smtp,ssmtp,imap2,imap3,imaps,pop3,pop3s
    #filter = sasl
    # You might consider monitoring /var/log/warn.log instead
    # if you are running postfix. See
    #logpath = /var/log/zimbra.log

    jail.conf contains data log path to be check and email address for banned notification. Do not forget to fill in the parameters ignoreip to prevent Fail2Ban banned internal network

  4. Edit file /etc/fail2ban/action.d/sendmail.conf and change the line :
    Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>


    Fail2Ban" | /opt/zimbra/postfix/sbin/sendmail -f <sender> <dest>
  5. Restart Fail2Ban services
    service fail2ban restart

Fail2Ban will sent a notification email to specified email address if found intrusion that match with Fail2Ban rule. IP will be instantly banned if it has qualified many times and match with Fail2Ban rules in a predefined time interval. We can also modify jail.conf  or create another regular expression to check other logs.

Below are screenshot of notification email from Fail2Ban:

Fail2Ban is quite powerful and can be used to anticipate the kind of brute-force attack, both on email and other server services such as web servers, FTP servers, database servers and others.

Leave a Reply

Your email address will not be published. Required fields are marked *