Zimbra 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 :
- 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 http://download.opensuse.org/repositories/security/SLE_11/ fail2ban zypper in fail2ban
- 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 $ # [Definition] # 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 =
- 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. [DEFAULT] # "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 = 127.0.0.1/8 202.43.115.188/32 # "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. [ssh-iptables] enabled = false filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] sendmail-whois[name=SSH, dest=zeze@vavai.com, sender=fail2ban@excellent.co.id] logpath = /var/log/messages maxretry = 5 # This jail forces the backend to "polling". [sasl-iptables] enabled = false filter = sasl backend = polling action = iptables[name=sasl, port=smtp, protocol=tcp] sendmail-whois[name=sasl, dest=support@excellent.co.id] logpath = /var/log/zimbra.log # Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is # used to avoid banning the user "myuser". [ssh-tcpwrapper] enabled = false filter = sshd action = hostsdeny sendmail-whois[name=SSH, dest=support@excellent.co.id] 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. [zimbra-account] enabled = true filter = zimbra action = iptables-allports[name=zimbra-account] sendmail[name=zimbra-account, dest=support@excellent.co.id] logpath = /opt/zimbra/log/mailbox.log bantime = 600 maxretry = 5 [zimbra-audit] enabled = true filter = zimbra action = iptables-allports[name=zimbra-audit] sendmail[name=Zimbra-audit, dest=support@excellent.co.id] logpath = /opt/zimbra/log/audit.log bantime = 600 maxretry = 5 [zimbra-recipient] enabled = true filter = zimbra action = iptables-allports[name=zimbra-recipient] sendmail[name=Zimbra-recipient, dest=support@excellent.co.id] logpath = /var/log/zimbra.log #findtime = 604800 bantime = 172800 maxretry = 5 [postfix] enabled = true filter = postfix action = iptables-multiport[name=postfix, port=smtp, protocol=tcp] sendmail-buffered[name=Postfix, dest=support@excellent.co.id] logpath = /var/log/zimbra.log bantime = -1 maxretry = 5 #[sasl] #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 http://bugs.debian.org/507990 #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
- Edit file /etc/fail2ban/action.d/sendmail.conf and change the line :
Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
into
Fail2Ban" | /opt/zimbra/postfix/sbin/sendmail -f <sender> <dest>
- 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.