SSL, Apache and Virtualhosting

I’ve got a few sites sitting on this poor web server, which all need SSL for things like webdav and administrative access. I don’t like the SSL errors that come up on the sites, as they all share an IP. To remedy this, I’ve created my own CA and have signed certificates that are good for multiple domains. I’ve distributed my root certificate to everyone who wants to trust me for the purpose of SSL on my sites, or any other certificates that I happen to sign.

There are quite a few sources of information on this around, but to get it to work in all browsers with my own CA required chopping bits together, which i’ll outline below.

Before you get started, consider the security implications of having a certificate that lists all of the sites you are using SSL on. If somebody inspects the certificate, they will see the entries for all of the sites you have included. This can allow an attacker to look for a weak application running on the server under a different domain. It can also have privacy implications.

First, I created a new CA, following this awesome Ubuntu document. There’s also an alternate method that leverages make files.

The biggest two issues I had with my CA configuration were:

  1. I set a subjectAltName value under my x509 extensions, which overwrote the requested data from the CSR.
  2. Under the CA policy, I didn’t match up required and optional fields, which also caused openssl to yell at me when signing the CSR.

After your CA is set up, you’ll need to get the CSR generated. Firstly, you need to configure the X509 extensions to include your extra data – At this point, it’s not possible to specify the data via the command line, but you can use the configuration file, or some cool environment variable magic.

Firstly, depending on the method chosen above, you’ll need to specify the alternate names. I decided to go the configuration file route. On the webserver, it ended up looking something like:


[ req ]
default_bits		= 1024
default_keyfile 	= server.key
distinguished_name	= dn
attributes		= req_attributes
string_mask = nombstr
req_extensions = v3_req # The extensions to add to a certificate request

[dn]
C = CA # Your Country Code
O = Organization Name
0.CN = *.domain1.com
1.CN = *.domain1.com
2.CN = *.domain1.com

[ v3_req ]
subjectAltName=@alt_names

[alt_names]
DNS.0 = *.domain1.com
DNS.1 = *.domain2.com
DNS.2 = *.domain3.com

From there you need to create your CSR, which requires a keyfile and a place to store it. I like to use /etc/apache2/ssl. Run the following

mkdir -p /etc/apache2/ssl
cd /etc/apache2/ssl
openssl genrsa -out server.key 1024
openssl req -new -text -config /etc/ssl/openssl.cnf -extensions v3_req

You’ll get a bunch of output and can verify your CNs and AltNames are correct. the CSR will be the bit at the end, but you can copy all of the output over to your CA for signing. I don’t usually keep my CSRs around, but as I add domains, I just run those commands to add them to my certificate.

Now, on your CA, assuming you’ve followed the Ubuntu documentation, run the following from your CA directory.

openssl ca -config caconfig.cnf -in ~/ssl/lako2.req -out server_crt.pem -preserveDN

Voila! you will now have a certificate that can support multiple hosts.

From there, you need to distribute your CA, and get apache to use your shiny new certificate. Getting your CA certificate out is as simple as placing your CA .cer file in a web accessible location. Have your users point their browser to it’s URL, and they should automatically be prompted to trust it.

My Apache SSL configuration, per site, is the same as the regular definition, with the following added. It’s taken almost straight from the stock Ubuntu SSL configuration.

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.
SSLEngine on

SSLCertificateFile    /etc/apache2/ssl/apache.pem
SSLCertificateKeyFile /etc/apache2/ssl/server.key

#   Server Certificate Chain:
#   Point SSLCertificateChainFile at a file containing the
#   concatenation of PEM encoded CA certificates which form the
#   certificate chain for the server certificate. Alternatively
#   the referenced file can be the same as SSLCertificateFile
#   when the CA certificates are directly appended to the server
#   certificate for convinience.
SSLCertificateChainFile /etc/apache2/ssl/server-ca.crt

#   SSL Engine Options:
#   Set various options for the SSL engine.

<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>

BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

If you end up adding additional sites, you can just modify your config files, regenerate the request and resign it.

15
Sep 2009
CATEGORY

Tech

COMMENTS 1 Comment
TAGS

,

One Response to “SSL, Apache and Virtualhosting”

  1. Randomed says:

    Good article, I had to do something similar when I was installing OCSi for my last job. The software pushes were secured over an ssl tunnel and I was also using vHosts to run more than 1 site on the box. To limit the number of errors I used more than 1 IP and created a Certificate that was also its own authoitor so both intranet sites would work.