The keys to supporting multiple sites using HTTPS and name-based virtual hosting are to use either wildcard names (specified in RFC2818) or the x509 version 3 certificate (specified in RFC3280) subject alternative names extension. I have not used wildcard names, although they allow one certificate to work for any number of hostnames below a given domain: *.example.com would allow any of a.example.com, foo.example.com, or elbow.example.com, but would not work for right.elbow.example.com or www.google.com. Wildcard certificates are much more expensive than standard certificates and are not administratively available in my particular work domain.
Subject alternative names, a.k.a. subjectAltNames, allow a certificate to list a number of host names for which it is valid. For example, a single certificate with www.example.com as its (single) subject could list www.example.com, www.example.org, and webapp.example.com as alternate names; the certificate would be recognized as valid for any of those host names.
Generating subjectAltName certificates
Convincing openssl to generate a certificate or certificate signing request requires changes to the openssl.conf file:
- Enable extensions:
[req]
req_extensions = v3_req - Add a v3_req section including the subjectAltName field:
[ v3_req ]
subjectAltName = @alt_names - List the host names in the proper format in the v3_req section:
[alt_names]
DNS.1 = web.example.com
DNS.2 = dspl.example.com
DNS.3 = nprop.example.com
DNS.4 = webdir.example.com
DNS.5 = hpps.example.com
DNS.6 = remoteuser.example.com
DNS.7 = esm.example.com
DNS.8 = etsapprover.example.com
DNS.9 = ep.example.com
DNS.10 = cas.example.com
DNS.11 = wat.example.com
DNS.12 = ned.example.com
For more information, see Creating a Certificate With Multiple Hostnames and a discussion from the OpenLDAP list.
Apache mod_rewrite
There are at least two ways of configuring httpd to handle multiple web sites with a single certificate. One resembles the normal name-based virtual hosting (with the VirtualHost directive and everything); the other is the one I have used.
In the first, set up httpd to listen on port 443 and to present the certificate with the subjectAltNames:
NameVirtualHost *:443
Listen 443
SSLEngine On
SSLCertificateFile /etc/....
SSLCertificateKeyFile /etc/.....
Then, add all of the necessary named virtual hosts normally, making sure that they are listening on port 443:
ServerName foo.example.com
# Configuration for web site foo.example.com
ServerName bar.example.com
# Configuration for web site bar.example.com
Now, I have not actually done this, but it looks like it should work.
What I have done is used subjectAltName certificates with a reverse proxy httpd configuration, where each of several applications in an application server appears to have its own server name:
Listen 443
SSLEngine On
SSLCertificateFile /etc/....
SSLCertificateKeyFile /etc/.....
RewriteEngine On
RewriteCond %{HTTP_HOST} ^foo\..*$
RewriteRule ^(.*) http://127.0.0.1:8090/foo-2.2$1 [P,L]
RewriteCond %{HTTP_HOST} ^bar\..*$
RewriteRule ^(.*) http://127.0.0.1:8090/bar-2.2$1 [P,L]
Issues
There are a couple of caveats: when present, the subject alt names list may or may not replace the actual subject of the certificate; if a host name is present only in the certificate subject field and is absent from the subjectAltName field then the browsers I have tried will not recognize the certificate as valid for the host name. Not all clients support subjectAltNames; see SAN Certificates: Subject Alternative Name. Further, there are possibly some security issues with multi-host certificates. Check Phishing for Confirmations for details.