Skip to main content

How to secure Zimbra Nginx to use strong encryption ciphers for TLS ?

Transport Layer Security (TLS) encrypts data sent over the Internet to ensure that eavesdroppers and hackers are unable to see what you transmit which is particularly useful for private and sensitive information such as passwords, credit card numbers, and personal correspondence. 
In this article we will learn how to secure Zimbra Nginx to use only strong encryption ciphers for TLS.
Check the following version:
root@mail:~# openssl version
OpenSSL 1.1.1  11 Sep 2018

zimbra@mail:~$ nginx -v
nginx version: nginx/1.20.0

zimbra@mail:~$ zmcontrol -v
Release 9.0.0.ZEXTRAS.20220713.UBUNTU18.64 UBUNTU18_64 FOSS edition. 
How to configure Protocol version TLSv1.3 to existing zimbraReverseProxySSLProtocols ? 
Check existing protocol version and Add TLSv1.3 to existing
Case 1: Example ( Add to existing )
$ zmprov gcf zimbraReverseProxySSLProtocols
zimbraReverseProxySSLProtocols: TLSv1 TLSv1.1 TLSv1.2

Now add TLSv1.3 to existing
$ zmprov mcf zimbraReverseProxySSLProtocols 'TLSv1 TLSv1.1 TLSv1.2 TLSv1.3' 
Case 2: Example ( Add to existing )
$ zmprov gcf zimbraReverseProxySSLProtocols
zimbraReverseProxySSLProtocols: TLSv1.2

$ zmprov mcf zimbraReverseProxySSLProtocols TLSv1.2
$ zmprov mcf +zimbraReverseProxySSLProtocols TLSv1.3 
Case 3: (recommended to use)
$ zmprov gcf zimbraReverseProxySSLProtocols  [no need to change]
zimbraReverseProxySSLProtocols: TLSv1.2
zimbraReverseProxySSLProtocols: TLSv1.3 
How to add TLSv1.3 cipher TLS_AES_256_GCM_SHA384 to existing zimbraReverseProxySSLCiphers ? 
Case 4: Example ( Add to existing )
$ zmprov gcf zimbraReverseProxySSLCiphers
zimbraReverseProxySSLCiphers: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4

$ zmprov mcf zimbraReverseProxySSLCiphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:TLS_AES_256_GCM_SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'
$ zmproxyctl restart 

Generate ssl_ciphers for use with zimbraReverseProxySSLCiphers

Since encryption is always evolving it is recommended to use Mozilla SSL Config generator that you can find at https://ssl-config.mozilla.org/

Select Intermediate and Nginx (Zimbra proxy is based on Nginx) at the time of writing this article this will select nginx 1.20.0 and OpenSSL 1.1.1. The tool also reports the oldest supported clients that work with this configuration: Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9. From the generated config file copy the value from ssl_ciphers:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 
Case 5: (recommended to use)
$ zmprov gcf zimbraReverseProxySSLCiphers ( check status )
zimbraReverseProxySSLCiphers: ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:TLS_AES_256_GCM_SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4

$ zmprov -l mcf zimbraReverseProxySSLCiphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'
$ zmproxyctl restart 
Configuring Zimbra Mailbox : 
Also configure Zimbra mailbox to allow the use of TLSv1.3. Open in a text editor /opt/zimbra/conf/localconfig.xml find the line mailboxd_java_options and set TLSv1.2,TLSv1.3 in https.protocols and jdk.tls.client.protocols
Example Result:
Then restart mailbox, or reboot your server:
$ zmmailboxdctl restart 
Configure additional HTTP headers
The following headers will:
  • Enable HTTP Strict Transport Security (HSTS)
  • Disable search indexing of your server by Google et al.
$ zmprov mcf +zimbraResponseHeader "Strict-Transport-Security: max-age=31536000; includeSubDomains"
$ zmprov mcf +zimbraResponseHeader "X-Content-Type-Options: nosniff"
$ zmprov mcf +zimbraResponseHeader "X-Robots-Tag: noindex"
$ zmprov mcf zimbraMailKeepOutWebCrawlers TRUE
$ zmmailboxdctl restart 
DH parameters
Use pre-defined DHE groups as recommended by IETF RFC 7919.
Further reading:
# wget https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem -O /etc/ffdhe4096.pem
# su - zimbra
$ zmprov mcf zimbraSSLDHParam /etc/ffdhe4096.pem 
# reboot
N.B: You can compare with [ curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/ffdhe2048.pem ] 
Don't forget to Reboot the Server.

Services

Most secure is to only allow secure methods of accessing the system; however, be careful in making these changes, as all processes need to be configured to connect only to upstream encrypted listeners.
1. Configure the proxy to offer only encrypted HTTPS protocols (run this on every proxy):
$ zmprov gs `zmhostname` zimbraReverseProxyMailMode
$ zmprov ms `zmhostname` zimbraReverseProxyMailMode https 
Note: it is possible to use "redirect" here, which will redirect HTTP requests to HTTPS using a "302 Redirect" response code. Please note, however, that some clients (such as ActiveSync devices) will not honor a 302 Redirect, and may try to pass unencrypted login information. It is recommended to use only https here for highest security.
2. Configure the mailstore to offer only encrypted HTTPS procotol:
$ zmprov gs `zmhostname` zimbraMailMode
$ zmprov ms `zmhostname` zimbraMailMode https 
3. Require Proxy to connect to upstream via SSL
$ zmprov gs `zmhostname` zimbraReverseProxySSLToUpstreamEnabled
$ zmprov ms `zmhostname` zimbraReverseProxySSLToUpstreamEnabled TRUE 
Encrypted Authentication 
All authentication must be done over TLS/SSL. Restart services after making these changes.
HTTP
$ zmprov gs `zmhostname` zimbraMailClearTextPasswordEnabled
$ zmprov ms `zmhostname` zimbraMailClearTextPasswordEnabled FALSE # if not already 
Configuring Admin UI
It is not recommended to expose the Admin UI to the Internet. Instead administrators should access Admin UI via a VPN. In any case you will need to make sure to proxy the Admin UI via Zimbra Proxy to make sure it uses the best TLS configuration. This means you should access Admin UI via the proxied port 9071, and deny access to port 7071 via a firewall. To enable this you should run as user Zimbra:
$ /opt/zimbra/libexec/zmproxyconfig -e -w -C -H `zmhostname`
$ zmproxyctl restart 
Source

Comments