Protecting Zimbra with Sucuri web application firewall

You can enhance the security of your Zimbra servers by using a web application firewall (WAF). By using a web application firewall you can add the following protections to Zimbra:

  • Geo blocking, geo fencing
  • Blocking or allow IP addresses
  • Emergency DDoS protection
  • Block anonymous proxies
  • Block top three attack countries
  • Manage HTTP Security Headers
  • Limited blocking of URL paths

While Zimbra offers DoSFilter, it’s configuration is command line based and not very easy to understand.

Prerequisites

To get started with a web application firewall, you need to first install Zimbra and set it up the usual way. You can use the Zimbra automated installer if you want to get started quickly.

For the Zimbra hostname you cannot use (registered) trademarks, including Sucuri. As those are not allowed to be added to the Sucuri service.

Eventually the web interface of Zimbra will only be accessible via the web application firewall and for that you will need to change the DNS. But for the initial installation you can set-up the DNS as follows (assuming your domain is zimbra.tech):

$ORIGIN zimbra.tech.
@        MX      100 wafmail.zimbra.tech.
@        TXT   "v=spf1 a mx -all"
_dmarc   TXT   "v=DMARC1; p=reject; fo=1"
@        CAA     0 issue "letsencrypt.org"
@        CAA     0 issue "godaddy.com"

waftest  A   [your zimbra server ip]
wafmail  A   [your zimbra server ip]

Please note the CAA records, Let’s Encrypt is used by the Zimbra automated installer, and GoDaddy is used by Sucuri.

You can install Zimbra using:

wget https://raw.githubusercontent.com/Zimbra/zinstaller/master/zinstaller -O /root/zinstaller
chmod +x /root/zinstaller
/root/zinstaller -p put-a-password-here -n waftest -t 'Europe/London' -a n --letsencrypt y zimbra.tech

If you want to use the web application firewall using a different hostname as configured in Zimbra you should consider the setting of zimbraReverseProxyStrictServerNameEnabled. Please leave this enable (true) if you have no issues.

zmprov mcf zimbraReverseProxyStrictServerNameEnabled false

Setting up Sucuri

Create an account for a 30-day trial at https://sucuri.net/website-firewall-a/free-trial/ the costs of Sucuri basic is $10/month at the time of writing this article. Once you have set-up your account you can add Zimbra  is shown in these screenshots:

image

image

Sucuri will then ask you to change your DNS so that the Zimbra web interface can be proxied via the web application firewall. This means you change the DNS as follows:

$ORIGIN zimbra.tech.
@        MX      100 wafmail.zimbra.tech.
@        TXT   "v=spf1 a mx -all"
_dmarc   TXT   "v=DMARC1; p=reject; fo=1"
@        CAA     0 issue "letsencrypt.org"
@        CAA     0 issue "godaddy.com"

waftest  A   [IP ADDRESS PROVIDED BY SUCURI]
wafmail  A   [your zimbra server ip]

Then you can refresh the page on the Sucuri dashboard to see the service is activated:

image

You should now be able to visit your Zimbra server via the web application firewall. Hopefully Sucuri has requested a new TLS certificate and you should have no issues. If needed you can upload TLS certificates to Sucuri via the dashboard.

Setting up a Firewall on Zimbra

To make sure no one can bypass the web application firewall you should set-up a host firewall on Zimbra. If you installed Zimbra with the automated installer you can find your firewall settings by running
iptables -L -n --line-numbers as root:

Chain INPUT (policy DROP)
num  target     prot opt source               destination
1    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x00
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 state NEW
3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x3F
4    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
5    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:143
7    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:993
8    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:995
9    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
10   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:465
11   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:587
12   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:9071
13   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
14   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:25
15   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
16   ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8 state NEW,RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 0 state RELATED,ESTABLISHED

Chain InstanceServices (0 references)
num  target     prot opt source               destination

As you can see port 443 is allowed in line 9, you can remove line 9 by running below command. Please verify your port 443 setting is indeed on line 9:

iptables -D INPUT 9

Then you can allow only the IP’s of Sucuri with the following commands:

iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -s 192.88.134.0/23 -j ACCEPT
iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -s 185.93.228.0/22 -j ACCEPT
iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -s 66.248.200.0/22 -j ACCEPT
iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -s 208.109.0.0/22 -j ACCEPT
netfilter-persistent save

You Zimbra server should now be protected by Sucuri

Zimbra 9 known-issues

For Zimbra 9 in some cases you will have to add the following to the Allow URL Paths setting in Sucuri:

^/service/soap

How to use Sucuri

The Sucuri dashboard is self explanatory. You can block countries from accessing your Zimbra server as shown in this screenshot:

image

You can also enable some of the advanced protection mechanisms:

image

You can also block single IP’s for known offenders:

image

Sucuri can block access to certain URL’s with the Block URL Paths feature. This could be a nice feature to mitigate zero-day security vulnerabilities. However the feature is very limited in what it sees as a match and is practically not usable.

image

Now that I use Sucury do I need to install Zimbra patches?

YES, Sucuri does not mitigate Zimbra security issues, even if it may be used to mitigate a security issue as a stop-gap measure, it is not a replacement of security fixes provided by patching.

A note on logging

In Zimbra you will see some changes in /opt/zimbra/log/audit.log and /opt/zimbra/log/audit.log, specifically in audit.log in case of a login attempt by admin@zimbra.tech, specifically the oip= value:

2022-11-01 09:58:26,438 INFO  [qtp758013696-432://localhost:8080/service/soap/BatchRequest] [name=admin@zimbra.tech;oip=[IP OF CLIENT], [IP OF SUCURI];ua=zclient/10.0.0_GA_4452;soapId=60a7ee51;] security - cmd=Auth; account=admin@zimbra.tech; protocol=soap

Similar for mailbox.log:

2022-11-01 11:48:04,540 INFO  [qtp1279309678-242:https://waftest.zimbra.tech/service/soap/BatchRequest] [name=admin@zimbra.tech;mid=2;oip=[IP OF CLIENT], [IP OF SUCURI];oproto=https;port=37866;ua=ZimbraXWebClient - GC107 (Linux)/10.0.0_GA_4452;soapId=635e8982;] soap - (batch) SearchRequest elapsed=30

However the Zimbra proxy (nginx based) logs such as /opt/zimbra/log/nginx.access.log they will not contain the IP of the client any longer:

[IP OF SUCURI]:14420 - - [01/Nov/2022:09:58:31 +0100]  "GET https://waftest.zimbra.tech/modern/index.js.map HTTP/1.1" 404 1327 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "[zimbra internal ip's]"

You can use the real-time logging in Sucuri as a replacement of the Zimbra Proxy log.

image

A note on fail2ban

If you are using fail2ban as described on the wiki you will want to disable the zimbra-webmail jail or update the filter filter.d/zimbra-webmail.conf to match the correct IP with the Securi set-up.

A note on Zimbra DosFilter

While some of the functionality between Zimbra’s Dosfilter overlap with Sucuri, you should use both and not disable Zimbra Dosfilter. Because Zimbra Dosfilter has the capability to suspend connections to IP’s for repeated failed logins. Repeated failed logins show up in /opt/zimbra/log/mailbox.log as follows:

2022-11-01 15:56:43,386 INFO  [qtp1279309678-23://localhost:8080/service/soap/BatchRequest] [] misc - Access from IP [CLIENT_IP], [SUCURI_IP] suspended, for repeated failed login.
2022-11-01 15:56:43,387 WARN  [qtp1279309678-106:https://waftest.zimbra.tech/] [] webclient - system failure: error while proxying request to target server: Service Unavailable
com.zimbra.common.service.ServiceException: system failure: error while proxying request to target server: Service Unavailable

Please note that even though the Securi IP address is listed in the log, the ban only applies to the IP of the client. Which means that Sucuri (and your other clients) are not blocked by Dosfilter. This also means that if  someone is using 1 IP to try passwords on admin@zimbra.tech and is suspended, admin@zimbra.tech can still log-in using a different IP.

For more information on Zimbra Dosfilter see: https://wiki.zimbra.com/wiki/DoSFilter

, ,

One Response to Protecting Zimbra with Sucuri web application firewall

  1. Franck CHALON January 19, 2023 at 1:04 AM #

    Hello,

    Thank you very much for the article.
    What would be really cool is to have explanations on the installation and configuration of Crowdsec on Zimbra. :)

Copyright © 2022 Zimbra, Inc. All rights reserved.

All information contained in this blog is intended for informational purposes only. Synacor, Inc. is not responsible or liable in any manner for the use or misuse of any technical content provided herein. No specific or implied warranty is provided in association with the information or application of the information provided herein, including, but not limited to, use, misuse or distribution of such information by any user. The user assumes any and all risk pertaining to the use or distribution in any form of any subject matter contained in this blog.

Legal Information | Privacy Policy | Do Not Sell My Personal Information | CCPA Disclosures