Monday, May 28, 2007

SSL: One Certificate, Multiple Domains

I was out trying to refresh my memory on how to set up SSL on Apache for Windows when I ran across a useful tip for allowing a single certificate to validate against multiple domains.

Just add the following line to your openssl.cnf file, in the [ v3_ca ] section:

subjectAltName = DNS:http://www.test.com,DNS:*.kensystem.com,DNS:*.etc.com

Apache2 Lounge: How-to More than one domain with your SSL

This could prove very useful, but I'll need to do some testing to see how it works.

Apache+SSL on Windows

I wanted to get SSL working on my server to enable a bit of security for things like checking mail remotely. Plus, there's always the possibility of me doing other things in the future with it.

Unfortunately, setting up SSL in Apache isn't nearly as easy as it is in IIS. Microsoft really does do a good job (eventually) with their GUI tools. The steps aren't really all that onerous, but a full step-by-step is difficult to find. I won't go into all the details, but this is enough to get going for me.

The first thing we need to do is, obviously, install Apache. I won't go into the details of configuring the server, that can easily take up a series of separate posts. For me, I found the Apache Lounge (AL) install after I had already set up using the MSI from the Apache Software Foundation (ASF). The nice thing about the AL install is that it will just drop in on top of the ASF one (be sure to back up your configuration files) and you get the benefit of the service already having been installed and the monitor set to run. Not that it's all that difficult to do, but it's nice to have it done for you.

Next, install OpenSSL. The process is fairly straightforward.

Now the tricky part, enable SSL in Apache. There's a lot of voodoo here related to PKI and encryption schemes, etc. There are a few tutorials out there (see the references), but I'll summarize here for brevity.
  1. Optional: set up your private key through OpenSSL:openssl genpkey -algoritm RSA -out key.pem(you don't have to do this as a private key can be generated for you in the next step)
  2. Generate your certificate signing request (CSR) that you will provide your certificate authority (such as CAcert):openssl req -config openssl.cnf -new -out my-server.csrIf you've already created your private key you have to specify it:openssl req -key keyfile.pem -config openssl.cnf -new -out my-server.csr
  3. At some point you have to remove the passphrase from the private key:openssl rsa -in privkey.pem -out my-server.keyIf you don't do this you'll have to type in the passphrase every time you start Apache ... which isn't an option if you're running Apache as a service. This does present a problem in that now your private key can be used by anyone who can get access to it. So be sure to keep your private key secured on your file system. Preferably somewhere only you (as an administrator) and your server user can access it.
  4. Submit the CSR to your CA and then drop the key they give you into your certificate/key store.
  5. Configure Apache (this may vary slightly depending on the version of Apache, I'm using 2.2.x) (trimmed to the stuff relevant to SSL, don't forget any other important parameters such as the document root):# Load SSL Module and instantiate
    LoadModule ssl_module modules/mod_ssl.so
    <ifmodule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    </ifmodule>

    # Set up SSL
    SSLCertificateKeyFile "server.key"
    Listen 443
    AddType application/x-x509-ca-cert .crt
    AddType application/x-pkcs7-crl .crl
    SSLPassPhraseDialog builtin
    SSLSessionCache "shmcb:ssl_scache(512000)"
    SSLSessionCacheTimeout 300
    SSLMutex default

    #Virtual Host Setup
    <virtualhost *:443>
    ServerName www.eclecticgeek.com

    SSLEngine on
    SSLCertificateFile site.crt
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

    <filesmatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
    </filesmatch>

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

    RewriteEngine on
    RewriteCond %{HTTPS} off [OR]
    RewriteRule ^/(.*) https://%{HTTP_HOST}:443/$1 [L,R]
    </virtualhost>
Unfortunately I don't remember why some of these settings had to be included. I'll update this as I have a chance to research more.

Performing a minor version upgrade is pretty simple:
  1. Install the updated OpenSSL package.
  2. Since we're using the Apache Lounge build of Apache2 with OpenSSL compiled in we need to update Apache as well.
    1. Download the zipped package
    2. Extract into a new directory
    3. Stop the Apache service
    4. Rename the previous install's directory
    5. Rename the new install's directory to match that used previously
    6. Copy the cert and conf directories from the previous install to the new one
    7. Start the service.
  3. Should be done with the upgrade, test to make sure.
Note: Apache has a version of the MSI installer with OpenSSL included, but it's a bit behind the current version.

Also note: this is a work in progress. Unfortunately I didn't write this stuff down when I initially set up SSL so I'm going based off my spotty memory and information I could find online.

References: