Zimbra Collaboration Server
- Using MailStore Archiving with Zimbra
- Make Zimbra only accept mail for existing accounts
- Mailbox Selected READ-ONLY Error in Thunderbird
- IPv6 and Zimbra 8
- Fixing the zmsaupdate cron-job
- SSL / TLS options
- Fixing the logrotate script
- Enabling SpamAssassin rule updates
- Adding Pyzor and Razor to SpamAssassin
- Using the ClamAV Unofficial Signatures
- Use Zimbra for system mail
- Synchronizing contacts with the macOS Contacts app (CardDAV)
- Remove submitting clients IP address from headers
Using MailStore Archiving with Zimbra
This is a short description of how I configure Zimbra to work with the MailStore archiving software.
Changes in configuration file /opt/zimbra/conf/amavisd.conf.in:
+++ amavisd.conf.in 2011-06-03 20:22:45.686544874 +0200
@@ -156,6 +156,10 @@
# $forward_method = 'smtp:[127.0.0.1]:10025'; # set to undef with milter!
%%uncomment SERVICE:archiving%%$archive_quarantine_method = 'smtp:[127.0.0.1]:10025';
+# Enable archiving to fixed e-mail address
+$archive_quarantine_method = 'smtp:[127.0.0.1]:10025';
+@archive_quarantine_to_maps = ('my-archiving-address@example.com');
+
%%uncomment VAR:zimbraAmavisQuarantineAccount%%$final_virus_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_DISCARD;
This should send every e-mail passed through Zimbra to the address my-archiving-address@example.com. This is the POP3 or IMAP mailbox that MailStore uses to receive all e-mails. Amavis will take care of writing headers that help MailStore identify to which e-mail address the e-mail actually belongs, so that it can be archived in the right MailStore account.
I have been using this configuration with ZCS 7.1, 7.2 and 8.6. For other versions, the configuration file and thus the changes might look different.
Make Zimbra only accept mail for existing accounts
By default, Zimbra accepts e-mails for addresses which are not valid and later sends a bounce mail. Unfortunately this can cause SPAM back-scatter and thus should be avoided (also see my blog article).
In Zimbra 8.6 it is very simple to change this behavior:
Effect on Hosts Listed in zimbraMtaMyNetworks
The change described above will have no effect on hosts listed in zimbraMtaMyNetworks. Therefore, if you have mail-server acting as a front-end to the Zimbra server, you should not list it in zimbraMtaMyNetworks. zimbraMtaMyNetworks should only contain the Zimbra server itself (and the loopback address).
However, for OpenDKIM and SpamAssassin, you also want to trust your other mail servers. You can get this effect by editing the configuration files and adding the appropriate IP addresses there:
/opt/zimbra/conf/opendkim-localnets.conf.in (Zimbra 8 only):
192.0.2.1/32
[2001:db8::1]/128
/opt/zimbra/conf/salocal.cf.in:
In recent Zimbra versions (ZCS 8.5 and newer) it might be more elegant to add your own trusted_networks line to /opt/zimbra/data/spamassassin/localrules/sauser.cf.
Important note: Earlier versions of this tutorial suggested also adding the hosts to the @mynetworks list in amavisd.conf.in. However, this is not a good idea because it will cause SpamAssassin to treat all e-mail as "submitted" by an authenticated client and thus it will also treat all hosts as trusted, even if it would not otherwise (as explained on the SpamAssassin mailing list). For this reason, zimbraMtaMyNetworks should only contain the Zimbra server itself and the @mynetworks option in the Amavis configuration should not be changed.
Mailbox Selected READ-ONLY Error in Thunderbird
Sometimes Thunderbird report the error "Mailbox selected READ-ONLY" when trying to move an e-mail from the inbox. The e-mail is copied to the target folder but not removed from the inbox. Besides the read flag will not be set correctly.
This problem seems to be related to the Ehcache feature in Zimbra. For me disable Ehcache solved the problem in Zimbra 7 and 8:
IPv6 and Zimbra 8
There are two potential problems when using Zimbra 8 on a IPv6-enabled host: The first problem concerns OpenLDAP and the second one concerns OpenDKIM.
Fixing the OpenLDAP Problem
Fixing the OpenLDAP problem is easy: Set the local configuration option ldap_bind_url to ldap:///:
After this change you have to restart Zimbra. For details refer to the article in my blog.
This change should survive minor Upgrades of Zimbra (e.g. from Zimbra 8.0.3 to Zimbra 8.0.5).
Fixing the OpenDKIM Problem
Fixing the OpenDKIM problem is a bit more tricky: You have to edit the file /opt/zimbra/conf/opendkim.conf.in and change the line
to
After this change you have to restart Zimbra. For details refer to the article in my blog.
Unfortunately, this change is overwritten when updating Zimbra, therefore it has to be applied again after each update.
Fixing the zmsaupdate cron-job
Some of versions of Zimbra (I noticed it in Zimbra 8.0.6) have a bug that causes the cron job for zmsaupdate to fail if /bin/sh is not pointing to a Bource Again Shell (Bash) (e.g. Ubuntu 12.04 LTS). The error message (send to the local zimbra user) looks like that:
/bin/sh: 36: [: Linux: unexpected operator
The fix for this is simple: The command has to be wrapped in a call to Bash. This can be done by editing Zimbra's crontab (crontab -u zimbra -e) and changing the line
to
SSL / TLS options
Disabling SSLv3
The article in the Zimbra Wiki extensively describes how to disable SSLv3. Since Zimbra 8.6, the supported TLS protocol versions can be controlled through the zimbraMailboxdSSLProtocols and zimbraReverseProxySSLProtocols options.
For adjusting the list of supported ciphers you might want to refer to the following sites:
- http://wiki.zimbra.com/wiki/Cipher_suites
- http://wiki.zimbra.com/wiki/Postfix_PCI_Compliance_in_ZCS
- http://wiki.zimbra.com/wiki/Weak_Cipher_Suites_Appear_in_Security_Scans
TLS Ciphers
Inspired by the BetterCrypto guide, I use the following settings (communication with other mail-servers always goes through another MTA, therefore I can be quite strict):
zmprov mcf zimbraMtaSmtpdTlsMandatoryCiphers high
zmprov mcf zimbraMtaSmtpdTlsExcludeCiphers aNULL,eNULL,LOW,3DES,MD5,EXP,PSK,DSS,RC4,SEED,ECDSA,DES
zmprov mcf zimbraMtaSmtpdTlsProtocols \!SSLv2,\!SSLv3
zmprov mcf zimbraReverseProxySSLCiphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
zmprov mcf +zimbraReverseProxySSLProtocols TLSv1.3
zmprov mcf -zimbraReverseProxySSLProtocols TLSv1
zmprov mcf -zimbraReverseProxySSLProtocols TLSv1.1
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_DSS_WITH_DES_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_RSA_WITH_DES_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_RSA_EXPORT_WITH_RC4_40_MD5
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_RSA_WITH_DES_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_RSA_WITH_RC4_128_MD5
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_RSA_WITH_3DES_EDE_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites SSL_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_128_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
zmprov mcf +zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_256_CBC_SHA
zmprov mcf +zimbraSSLExcludeCipherSuites TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
A word regarding the ciphers and protocols that we configure for the reverse proxy: We disable TLS 1.0 and 1.1 because they are not considered secure any longer and most browsers have dropped support for them anyway. We enable all TLSv1.3 ciphers because they seem to be enabled anyway, even if we do not list them. We prefer 256 bit ciphers over 128 bit ciphers. A minimal modern list supporting both TLSv1.2 and TLSv1.3 would look like this:
We include the CHACHA20 ciphers because some systems that do support them do not support AES256, and they should be better than AES128.
In addition to that list, we add the AES128-GCM ciphers because Android 5.0 and 6.0 apparently neither support AES256 nor CHACHA20. We add the CBC ciphers to the end of the list, because IE 11 on Windows 8.1 (and Windows Server 2012 R2) does not support GCM yet. The AES256-CBC variant would be sufficient for that, but also supporting AES128-CBC also gives us support for IE11 on Windows Phone 8.1, and it is probably not significantly more insecure than AES256-CBC.
It probably is a good idea to completely remove the AES-CBC ciphers when Windows 8.1 / Windows Server 2012 R2 drop out of support in 2023.
In addition to these changes, it makes sense to enable TLSv1.3 and disable TLSv1.0 and TLSv1.1 for mailboxd. This happens through zmlocalconfig. Run zmlocalconfig mailboxd_java_options to display the current options and edit the https.protocols and jdk.tls.client.protocols options. Then set the resulting string through zmlocalconfig. For example:
Strict-Transport-Security Header
It makes sense to add the Strict-Transport-Security header so that the web interface is never used through an unencrypted connection. I got the idea here). I use these settings with Zimbra 8.6.
Typically, the add_header option needs to be added to two files:
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.https.default.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.https.template
The option is added in the following form and add it right after the ssl_verify_depth option:
Since Zimbra 8.7 there is a simpler option for adding this header:
If you enable the Nginx proxy for the first time, do not forget to (re-)enable the redirect mode (unless you are using the pure https mode):
You also might have to configure the protocol and hostname used for generating URLs (otherwise, some generated URLs might use the http scheme):
zmprov md <domain> zimbraPublicServiceProtocol https
Adjusting the DH key size
By default, Nginx only uses 1024 bit keys when using the TLS_DH_* ciphers (Diffie-Hellman key exchange). This is not considered enough any longer. In order to increase this size, the Diffie-Hellman parameters need to be configured explicitly. I am using the following settings with Zimbra 8.6.
First, the DH parameters need to be generated with OpenSSL:
Next, the ssl_dhparam option has to be added to the relevant sections of the Nginx configuration. I added it to the following configuration files, right before the ssl_ecdh_curve option:
- /opt/zimbra/conf/nginx/templates/nginx.conf.mail.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.admin.default.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.admin.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.https.default.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.https.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.sso.default.template
- /opt/zimbra/conf/nginx/templates/nginx.conf.web.sso.template
The configuration line should look like this:
Starting with Zimbra 8.7, Zimbra uses 2048 bit DH params by default and this manual intervention is not necessary any longer.
Fixing the logrotate script
The logrotate script (/etc/logrotate.d/zimbra) for the Nginx log files has a small problem (Bug 106800): It might happen, that the compression of the logfile starts before Nginx has stopped writing to the logfile. This might result in an e-mail with the following content being sent to the administrator:
gzip: stdin: file size changed while zipping
At the moment, I am testing the following workaround for this issue: I changed the logrotate script to wait for five seconds after sending SIGUSR1 to Nginx. This should allow Nginx to reopen the file:
kill -USR1 `cat /opt/zimbra/log/nginx.pid 2> /dev/null` 2> /dev/null && sleep 5 || true
endscript
If this does not help, the delaycompress option should fix it for sure.
Enabling SpamAssassin rule updates
Since Zimbra 8, it might be necessary to explicitly enable SpamAssassin rule updates (see this article in the Zimbra knowledge-base). You can do this through zmlocalconfig:
zmlocalconfig -e antispam_enable_restarts=true
zmlocalconfig -e antispam_enable_rule_compilation=true
The last line is only necessary if you want to compile rules (this should improve the scan performance).
Adding Pyzor and Razor to SpamAssassin
This has been heavily inspired by https://wiki.zimbra.com/wiki/Improving_Anti-spam_system and https://wiki.zimbra.com/wiki/Anti-spam_Strategies, but it use a different path for the configuration files so that they do not get lost during a Zimbra upgrade.
Pyzor
Install the package (as root):
Create a symbol link in the Zimbra directory (as root):
Run all remaining actions as the zimbra user (su - zimbra).
Create the configuration directory:
Create a symbol link in the amavisd directory:
Optionally, increase the timeout for Pyzor by adding the pyzor_timeout option to the SpamAssassin configuration. For example:
In recent Zimbra versions, you can add this line to /opt/zimbra/data/spamassassin/localrules/sauser.cf.
Razor
Install the package (as root):
Create a symbol link in the Zimbra directory (as root):
Run all remaining actions as the zimbra user (su - zimbra).
Create the configuration directory:
Create a symbol link in the amavisd directory:
Initialize the configuration:
razor-admin -discover
razor-admin -register
Using the ClamAV Unofficial Signatures
Adding more signatures to ClamAV can help in improving the detection rate for virus scans. The ClamAV Unofficial Signatures Updater is available from GitHub. In order to install the script, one should download the newest release in the .tar.gz format from the releases page (version 5.4.1 in this example) and unpack it in /opt/zimbra. One should then create a symbol-link from clamav-unofficial-sigs to the directory created when unpacking the archive and make the script executable, for example:
chmod a+x /opt/zimbra/clamav-unofficial-sigs/clamav-unofficial-sigs.sh
All remaining steps should be done as the zimbra user.
Create directories for the script’s configuration and data:
mkdir /opt/zimbra/data/clamav-unofficial-sigs
Copy the master.conf and example user.conf from the distribution to the configuration directory:
cp /opt/zimbra/clamav-unofficial-sigs/config/user.conf /opt/zimbra/conf/clamav-unofficial-sigs
Create a /opt/zimbra/conf/clamav-unofficial-sigs/os.conf file that contains OS-specific paths, etc. As these paths differ from the ones typically used for the operating system (Zimbra brings its own version of ClamAV), one cannot use one of the example files. The following file works with Zimbra 8.7 on Ubuntu 14.04 LTS and with the ClamAV Unofficial Signatures Updater 5.4.1, but changes might be needed when using a different version of Zimbra, a different operating system, or a differet version of the updater script.
###################
# This is property of eXtremeSHOK.com
# You are free to use, modify and distribute, however you may not remove this notice.
# Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
##################
#
# Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
#
# Originially based on:
# Script provide by Bill Landry (unofficialsigs@gmail.com).
#
# License: BSD (Berkeley Software Distribution)
#
##################
#
# NOT COMPATIBLE WITH VERSION 3.XX / 4.XX CONFIG
#
################################################################################
# SEE MASTER.CONF FOR CONFIG EXPLAINATIONS
################################################################################
# Rename to os.conf to enable this file
################################################################################
# Zimbra
clam_user="zimbra"
clam_group="zimbra"
clam_dbs="/opt/zimbra/data/clamav/db"
clamd_pid="/opt/zimbra/log/clamd.pid"
clamd_restart_opt="/opt/zimbra/bin/zmclamdctl restart"
clamd_reload_opt="/opt/zimbra/common/bin/clamdscan --config-file=/opt/zimbra/conf/clamd.conf --reload"
clamscan_bin="/opt/zimbra/common/bin/clamscan"
#clamd_socket="/var/run/clamav/clamd.ctl"
work_dir="/opt/zimbra/data/clamav-unofficial-sigs"
log_file_path="/opt/zimbra/log"
# https://eXtremeSHOK.com ######################################################
One also has to make some modifications to the user.conf file. As an absolute minimum, the line user_configuration_complete="yes" has to be added or the updater script will not work. I also chose to set the following options:
malwarepatrol_enabled="no" # Malware Patrol
downloader_ignore_ssl="no" # do not ignore SSL (certifcate) errors when
# downloading files
Finally, one has to add the following line to the crontab file of the zimbra user (crontab -u zimbra -e):
45 * * * * /bin/bash /opt/zimbra/clamav-unofficial-sigs/clamav-unofficial-sigs.sh -c /opt/zimbra/conf/clamav-unofficial-sigs >/dev/null
it is a good idea to once run this script manually in order to see whether everything is working (/bin/bash /opt/zimbra/clamav-unofficial-sigs/clamav-unofficial-sigs.sh -c /opt/zimbra/conf/clamav-unofficial-sigs).
After running the script, one can check whether ClamAV is actually using the signatures by running clamscan --debug -d /opt/zimbra/data/clamav/db /dev/null 2>&1|grep loaded. In addition to the regular ClamAV signatures, one should see the signatures added by the updater script (the exact list depends on the configuration).
Use Zimbra for system mail
The paths are for Zimbra 8.7:
--install /usr/sbin/sendmail mta /opt/zimbra/common/sbin/sendmail 25 \
--slave /usr/bin/mailq mta-mailq /opt/zimbra/common/sbin/mailq \
--slave /usr/bin/newaliases mta-newaliases /opt/zimbra/common/sbin/newaliases \
--slave /usr/share/man/man1/mailq.1.gz mta-mailqman /opt/zimbra/common/share/man/man1/mailq.1 \
--slave /usr/share/man/man1/newaliases.1.gz mta-newaliasesman /opt/zimbra/common/share/man/man1/newaliases.1 \
--slave /usr/share/man/man8/sendmail.8.gz mta-sendmailman /opt/zimbra/common/share/man/man1/sendmail.1 \
--slave /usr/share/man/man5/aliases.5.gz mta-aliasesman /opt/zimbra/common/share/man/man5/aliases.5
Synchronizing contacts with the macOS Contacts app (CardDAV)
Contacts that are stored in Zimbra can be synchronized with the macOS Contacts app through the CardDAV protocol. However, there seems to be one severe limitation at least up to macOS 10.12.5 (Sierra). Only one address book can be synchronized. If there is more than one address book, the “first” one is selected. In this case, “first” seems to be decided based on the lexical order. In my case, I had an extra address book starting with the letter “A” and this one would be chosen instead of the standard “Contacts” address book. I could fix this by renaming the extra address book.
Remove submitting clients IP address from headers
By default, the IP address of the client that submitted an e-mail is visible through the Received header added by Postfix. This might not be desirable for privacy reasons. I got the basic idea from here, but I had to adapt it to make it work with Zimbra 8.8.
We add the following lines to /opt/zimbra/conf/postfix_header_checks.in:
IGNORE
/^X-Originating-IP:/
IGNORE
Please note that there is a tab (not spaces) in front of IGNORE.
Unfortunately, Zimbra does not use the header checks file by default and manually setting the header_checks option in Postfix's main.cf does not work either, because it is overwritten when Postfix is started. There are two ways to fix this. One can either set the zimbraMtaBlockedExtensionWarnRecipient configuration option to FALSE like suggested here:
The other solution is changing the configuration of zmconfigd by removing the following lines from /opt/zimbra/conf/zmconfigd.cf:
POSTCONF header_checks
fi
Most likely, you also want to set the zimbraSmtpSendAddOriginatingIP to FALSE: