Hosting Multiple SSL Sites on Apache the Easy Way

Updated 2/9/2015: Instructions for Apache 2.4 included

The first time I ever installed an SSL certificate was a frustrating, awful experience that I’d rather just forget. It involved four cups of coffee and a terminal window open from 4pm on a Saturday afternoon until 4am on a cold Sunday morning two winters ago. Since then I’ve installed SSL certificates countless times and the truth is it’s not so bad when you’re installing them under Apache for a single IP address. Now, hosting two SSL enabled sites on Apache is a different story, or so I was always told. Turns out that hosting multiple SSL enabled sites under Apache is 99% the same as hosting just one SSL enabled site on Apache. Here’s how you can do it.

Step 1: IP configuration

First off, this is not a guide to show you how to host multiple SSL sites under one IP. From what I understand that really is a big fat pain so its best to just avoid it. And honestly, there’s not many reasons why you couldn’t avoid this scenario anyway. If you’re manually installing an SSL certificate onto a dedicated or VPS server then you most likely have the option to buy an additional IP. I did. I host my sites with Linode and right now my servers don’t see enough load to justify buying more, so I just bought a second IP for a year (for $12) from Linode. I got it within a few minutes and then I was off to the races…

Set up static networking

Your server is probably only configured to use a single public IP and possibly one private one too. The first thing to do when you get your second IP address is to configure static networking. That link is for Linode’s guides which will work for any VPS provider so long as you’re running some common Linux distro. Static networking is a bit beyond the scope of this post but in a nutshell you’ll need to open up your /etc/network/interfaces file in a text editor like vi, nano, or pico and edit it so it looks like this (replacing your settings where marked)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# The loopback interface
auto lo
iface lo inet loopback

# Configuration for eth0 and aliases

# This line ensures that the interface will be brought up during boot.
auto eth0 eth0:0 eth0:1

# eth0 - This is the main IP address that will be used for most outbound connections.
# The address, netmask and gateway are all necessary.
iface eth0 inet static
 address 12.34.56.78
 netmask 255.255.255.0
 gateway 12.34.56.1

# eth0:0
# This is a second public IP address.
iface eth0:0 inet static
 address 34.56.78.90
 netmask 255.255.255.0

# eth0:1 - Private IPs have no gateway (they are not publicly routable) so all you need to
# specify is the address and netmask.
iface eth0:1 inet static
 address 192.168.133.234
 netmask 255.255.128.0

Before we move on, let me note a few things. If you don’t have a private IP and that third config stanza (the one that starts with iface eth0:1) doesn’t already exist in your interfaces file, you should leave it out. Also, the first public IP you configure (in this example it’s eth0) should have one gateway declared however the second public IP should NOT declare a gateway even if you do have one. In addition, often times with a second IP you’ll get another gateway that closely resembles the IP. When you configure the gateway for the first public IP, be sure to declare the gateway that matches the IP address closest. For example, if your IP was 12.34.56.78 then your gateway would most likely look like 12.34.56.1. If your IPs and gateways don’t resemble each other at all then ignore this advice completely.

Set your reverse DNS

This part’s easy. Most hosting companies have a pretty nice UI for setting reverse DNS. Since I’m using Linode I’ll show you what I have to do. I log into my Linode Manager, go to the Dashboard, click Remote Access, then right under my IP addresses there’s a link that lets me set reverse DNS. It looks like this:

Once I click that link, I type in a domain name that I want to use as reverse DNS for a certain IP. So long as that domain’s A/AAA record is using that same IP, Linode detects it and asks me if I want to use the domain for reverse DNS on that IP. I say yes and we’re done.

Create the site using VirtualHosts

So now we have an IP and networking all set up for hosting a site on a different IP. All that’s left is to feed Apache the right config directives. This part is easy

Assumptions:

At this point I assume you’ve already generated an SSL certificate signing request (CSR file) and have received your signed certificate(s). I also assume you have placed them in the right folder on your server (/etc/apache2/ssl). If not, please do so. But that’s beyond the scope of this post. Moving on now…

Create the VHost file

This part is easy – follow these steps:

  1. Run touch /etc/apache2/sites-available/mydomain.com then nano /etc/apache2/sites-available/mydomain.com

  2. Now in your favorite text editor, add in your host configuration for the new SSL enabled site. NOTE: At this point I assume you already have other sites living on your first IP with maybe even an SSL enabled site on there too. That’s fine, you do not need to change their configuration to continue – you only have to set the config for the new SSL site that’ll live on the new IP. Your Vhost file should look like this:

Virtual Host Config for SSL on second IP
1
2
3
4
5
6
7
8
9
10
11
12
13
# This is for a site hosted on your NEW IP so be sure to use that in this config
<VirtualHost 12.34.56.78:443>
     SSLEngine On
     SSLCertificateFile /etc/apache2/ssl/www.mydomain.com.crt
     SSLCertificateKeyFile /etc/apache2/ssl/www.mydomain.com.key
     SSLCACertificateFile /etc/apache2/ssl/verisign.cer

     ServerAdmin info@mydomain.com
     ServerName www.mydomain.com
     DocumentRoot /var/www/mydomain.com/public_html/
     ErrorLog /var/www/mydomain.com/logs/error.log
     CustomLog /var/www/mydomain.com/logs/access.log combined
</VirtualHost>

Optionally, if you plan to allow people to access the site over non-SSL connections, you’d add the very same configuration ABOVE the one we just went through with the following exceptions: the port will be :80 instead of :443 and the first 4 lines referencing SSL should be deleted.

  1. Now make sure those folders exist by running:
Create a place on disk for new site to live
1
2
3
# You may need to run 'sudo' for this to work
mkdir -p /var/www/mydomain.com/public_html
mkdir /var/www/mydomain.com/log
  1. (Update: If you use Apache 2.4 then skip this step – Ubuntu 14.04 and later will install Apache 2.4 if you used apt-get) Add a line to your ports.conf file. You’ll find ports.conf in /etc/apache2. So we run nano /etc/apache2/ports.conf (again, you may need to put sudo before that command) and then add this line to that file right below where you may see a line looking very similar to it:
NameVirtualHost directive
1
NameVirtualHost 12.34.56.78:443
  1. You’re done! Not really. One more thing to do – enable the site and restart Apache so run these two commands in this order:
Enable new site and activate it
1
2
sudo a2ensite mydomain.com
sudo service apache2 restart

If all went well then you should get a couple messages saying “Enabling site…done” and “Restarting Apache…done”.

Now, that was easy, right? I’m a long-winded guy so I put maybe too much detail into this but it really is basic. It used to be a huge chore to mess with server configurations and it still trips me up since I’m more of a developer than anything else but it turns out that managing a web server is actually pretty straightforward once you get used to the command line and learn where a few key files live.

Security, Web application development, Web development

« Show Hidden Files and Folders on a Mac How to do a hard thing »

Comments