Difference between revisions of "Multiple SSL Virtual Hosts"

Line 1: Line 1:
[[ZimbraApache|Reverse proxy configuration]]
+
It may be required to provide SSL connections to the mailstore for more than one virtual host on a Zimbra server.  While this is not natively possible with Tomcat, there is a workable solution with Apache and [[ZimbraApache|reverse proxy]] (mod_proxy).  This configuration can work with or without setting Zimbra's domain "Virtual Host" parameter and can be a great substitution for managing SSL connections with Apache instead of Tomcat.
  
 
==== Configure Zimbra ====
 
==== Configure Zimbra ====
Line 5: Line 5:
 
  $ zmprov ms `zmhostname` zimbraMailMode http
 
  $ zmprov ms `zmhostname` zimbraMailMode http
 
  $ zmprov ms `zmhostname` zimbraMailPort 8080
 
  $ zmprov ms `zmhostname` zimbraMailPort 8080
 +
$ tomcat restart
  
 
==== Use Zimbra's CA to Generate Self-Signed Certificates for Apache ====
 
==== Use Zimbra's CA to Generate Self-Signed Certificates for Apache ====
   
+
Create self-signed certificates for testing the configuration.  
 +
 
 
  $ mkdir /etc/httpd/conf/domaina_ssl; cd /etc/httpd/conf/domaina_ssl
 
  $ mkdir /etc/httpd/conf/domaina_ssl; cd /etc/httpd/conf/domaina_ssl
  
Line 14: Line 16:
 
  > -newkey rsa:1024 -config /opt/zimbra/ssl/ssl/zmssl.cnf
 
  > -newkey rsa:1024 -config /opt/zimbra/ssl/ssl/zmssl.cnf
  
Process the certificate request
+
Process the certificate request.
 
  $ openssl ca -out host.zmb.moc.crt -notext -config /opt/zimbra/ssl/ssl/zmssl.cnf \
 
  $ openssl ca -out host.zmb.moc.crt -notext -config /opt/zimbra/ssl/ssl/zmssl.cnf \
 
  > -in zimbra.domaina.moc.csr -keyfile /opt/zimbra/ssl/ssl/ca/ca.key -cert /opt/zimbra/ssl/ssl/ca/ca.pem -batch
 
  > -in zimbra.domaina.moc.csr -keyfile /opt/zimbra/ssl/ssl/ca/ca.key -cert /opt/zimbra/ssl/ssl/ca/ca.pem -batch
Line 21: Line 23:
  
 
Apache or Tomcat will not do name-based virtual hosting over SSL because the SSL layer is lower than the HTTP layer which results in the host header being read after the SSL handshake.  This is the major conundrum.  Please read http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html#vhosts for a detailed explanation.  Separate IP addresses or listener ports must be assigned to get around the problem.
 
Apache or Tomcat will not do name-based virtual hosting over SSL because the SSL layer is lower than the HTTP layer which results in the host header being read after the SSL handshake.  This is the major conundrum.  Please read http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html#vhosts for a detailed explanation.  Separate IP addresses or listener ports must be assigned to get around the problem.
 +
 +
/etc/httpd/conf/httpd.conf:
 +
NameVirtualHost *:80
  
 
/etc/httpd/conf.d/zimbra_proxy.conf assigning a separate IP for each virtual host:
 
/etc/httpd/conf.d/zimbra_proxy.conf assigning a separate IP for each virtual host:
Line 58: Line 63:
 
  </Proxy>
 
  </Proxy>
 
  <nowiki></nowiki>
 
  <nowiki></nowiki>
Listen 1443
+
  Listen 1443
  <VirtualHost *:1443>
+
  <VirtualHost _default_:1443>
 
   ServerName zimbra.domaina.moc
 
   ServerName zimbra.domaina.moc
 
   ProxyPass / <nowiki>http://zimbra.domain.moc:8080/</nowiki>
 
   ProxyPass / <nowiki>http://zimbra.domain.moc:8080/</nowiki>
Line 70: Line 75:
 
  <nowiki></nowiki>
 
  <nowiki></nowiki>
 
  Listen 2443
 
  Listen 2443
  <VirtualHost *:2443>
+
  <VirtualHost _default_:2443>
 
   ServerName zimbra.domainb.moc
 
   ServerName zimbra.domainb.moc
 
   ProxyPass / <nowiki>http://zimbra.domain.moc:8080/</nowiki>
 
   ProxyPass / <nowiki>http://zimbra.domain.moc:8080/</nowiki>
Line 79: Line 84:
 
   SSLCertificateFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.crt
 
   SSLCertificateFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.crt
 
  </VirtualHost>
 
  </VirtualHost>
 +
 +
If being forced to supply a port number is not desired, force a redirect using mod_rewrite in .htaccess files. Append to /etc/httpd/conf.d/zimbra_proxy.conf:
 +
<VirtualHost *:80>
 +
  ServerName zimbra.domaina.moc
 +
  DocumentRoot "/var/www/domaina"
 +
  <Directory "/var/www/domaina">
 +
      AllowOverride Options FileInfo AuthConfig
 +
  </Directory>
 +
</VirtualHost>
 +
<nowiki></nowiki>
 +
<VirtualHost *:80>
 +
  ServerName zimbra.domainb.moc
 +
  DocumentRoot "/var/www/domainb"
 +
  <Directory "/var/www/domainb">
 +
      AllowOverride Options FileInfo AuthConfig
 +
  </Directory>
 +
</VirtualHost>
 +
 +
/var/www/domaina/.htaccess:
 +
RewriteEngine On
 +
RewriteCond %{SERVER_PORT} !1443
 +
RewriteRule ^(.*)$ <nowiki>https://%{HTTP_HOST}:1443%{SERVER_URI}</nowiki>
 +
 +
/var/www/domainb/.htaccess:
 +
RewriteEngine On
 +
RewriteCond %{SERVER_PORT} !2443
 +
RewriteRule ^(.*)$ <nowiki>https://%{HTTP_HOST}:2443%{SERVER_URI}</nowiki>
 +
 +
Be sure to restart httpd.

Revision as of 04:35, 24 May 2007

It may be required to provide SSL connections to the mailstore for more than one virtual host on a Zimbra server. While this is not natively possible with Tomcat, there is a workable solution with Apache and reverse proxy (mod_proxy). This configuration can work with or without setting Zimbra's domain "Virtual Host" parameter and can be a great substitution for managing SSL connections with Apache instead of Tomcat.

Configure Zimbra

$ su - zimbra
$ zmprov ms `zmhostname` zimbraMailMode http
$ zmprov ms `zmhostname` zimbraMailPort 8080
$ tomcat restart

Use Zimbra's CA to Generate Self-Signed Certificates for Apache

Create self-signed certificates for testing the configuration.

$ mkdir /etc/httpd/conf/domaina_ssl; cd /etc/httpd/conf/domaina_ssl

Create a certificate request.

$ openssl req -new -nodes -out host.zmb.moc.csr -keyout zimbra.domaina.moc.key \
> -newkey rsa:1024 -config /opt/zimbra/ssl/ssl/zmssl.cnf

Process the certificate request.

$ openssl ca -out host.zmb.moc.crt -notext -config /opt/zimbra/ssl/ssl/zmssl.cnf \
> -in zimbra.domaina.moc.csr -keyfile /opt/zimbra/ssl/ssl/ca/ca.key -cert /opt/zimbra/ssl/ssl/ca/ca.pem -batch

Configure httpd

Apache or Tomcat will not do name-based virtual hosting over SSL because the SSL layer is lower than the HTTP layer which results in the host header being read after the SSL handshake. This is the major conundrum. Please read http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html#vhosts for a detailed explanation. Separate IP addresses or listener ports must be assigned to get around the problem.

/etc/httpd/conf/httpd.conf:

NameVirtualHost *:80

/etc/httpd/conf.d/zimbra_proxy.conf assigning a separate IP for each virtual host:

ProxyRequests Off
<Proxy *>
  Order deny,allow
  Deny from all
  Allow from all
</Proxy>

<VirtualHost 1.1.1.1:443>
  ServerName zimbra.domaina.moc
  ProxyPass / http://zimbra.domain.moc:8080/
  ProxyPassReverse / http://zimbra.domain.moc:8080/
  SSLEngine On
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
  SSLCertificateKeyFile /etc/httpd/conf/domaina_ssl/zimbra.zmb.moc.key
  SSLCertificateFile /etc/httpd/conf/domaina_ssl/zimbra.zmb.moc.crt
</VirtualHost>

<VirtualHost 1.1.1.2:443>
  ServerName zimbra.domainb.moc
  ProxyPass / http://zimbra.domain.moc:8080/
  ProxyPassReverse / http://zimbra.domain.moc:8080/
  SSLEngine On
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
  SSLCertificateKeyFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.key
  SSLCertificateFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.crt
</VirtualHost>

Alternate /etc/httpd/conf.d/zimbra_proxy.conf assigning separate SSL listener ports for each domain:

ProxyRequests Off
<Proxy *>
  Order deny,allow
  Deny from all
  Allow from all
</Proxy>

 Listen 1443
<VirtualHost _default_:1443>
  ServerName zimbra.domaina.moc
  ProxyPass / http://zimbra.domain.moc:8080/
  ProxyPassReverse / http://zimbra.domain.moc:8080/
  SSLEngine On
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
  SSLCertificateKeyFile /etc/httpd/conf/domaina_ssl/zimbra.zmb.moc.key
  SSLCertificateFile /etc/httpd/conf/domaina_ssl/zimbra.zmb.moc.crt
</VirtualHost>

Listen 2443
<VirtualHost _default_:2443>
  ServerName zimbra.domainb.moc
  ProxyPass / http://zimbra.domain.moc:8080/
  ProxyPassReverse / http://zimbra.domain.moc:8080/
  SSLEngine On
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
  SSLCertificateKeyFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.key
  SSLCertificateFile /etc/httpd/conf/domainb_ssl/zimbra.domainb.moc.crt
</VirtualHost>

If being forced to supply a port number is not desired, force a redirect using mod_rewrite in .htaccess files. Append to /etc/httpd/conf.d/zimbra_proxy.conf:

<VirtualHost *:80>
  ServerName zimbra.domaina.moc
  DocumentRoot "/var/www/domaina"
  <Directory "/var/www/domaina">
     AllowOverride Options FileInfo AuthConfig
  </Directory>
</VirtualHost>

<VirtualHost *:80>
  ServerName zimbra.domainb.moc
  DocumentRoot "/var/www/domainb"
  <Directory "/var/www/domainb">
     AllowOverride Options FileInfo AuthConfig
  </Directory>
</VirtualHost>

/var/www/domaina/.htaccess:

RewriteEngine On
RewriteCond %{SERVER_PORT} !1443
RewriteRule ^(.*)$ https://%{HTTP_HOST}:1443%{SERVER_URI}

/var/www/domainb/.htaccess:

RewriteEngine On
RewriteCond %{SERVER_PORT} !2443
RewriteRule ^(.*)$ https://%{HTTP_HOST}:2443%{SERVER_URI}

Be sure to restart httpd.

Jump to: navigation, search