It is possible with Apache to host multiple websites with a single static IP address. However, you can only have one SSL certificate per static IP. This post describes setting up Apache with multiple secure virtual hosts and a single self-signed wildcard certificate. To learn about creating the certificate, check out Creating Self-Signed Certs on Apache 2.2.
Here’s a table of our example hosts:
| Domain | Force SSL? | Trusted? | Valid Domain? |
|---|---|---|---|
| www.site-a.com | No | No | Yes |
| secure.site-a.com | Yes | No | Yes |
| test.site-a.com | No | No | Yes |
| www.site-b.com | No | No | No |
| secure.site-b.com | Yes | No | No |
In order for the certificate to be trusted, you need to obtain the certificate from a trusted certificate authority. Since we are using self-signed certificates, they are not trusted and we will see some warning messages. The data will still be encrypted.
For this to work, we are going to use name-based virtual hosts.
The name and location of Apache’s configuration files vary based on which platform you use. This post assumes Ubuntu in which case the configuration files in the /etc/apache2 directory.
For starters, we need to tell Apache which ports to listen on by editing the file /etc/apache2/ports.conf.
Listen 80
<IfModule mod_ssl.c>
Listen 443
</IfModule>
Next we need to add our virtual hosts. They are kept in the /etc/apache2/sites-available directory. For organization purposes, separate your sites into separate config files, then run a2ensite for each site to generate a symbolic link in the /etc/apache2/sites-enabled directory.
Here is the configuration for the sites:
NameVirtualHost 192.168.1.200:80 NameVirtualHost 192.168.1.200:443 # http://site-a.com # https://site-a.com -- Throws warning because cert is for *.site-a.com... see bottom # http://www.site-a.com # https://www.site-a.com <VirtualHost 192.168.1.200:80 192.168.1.200:443> ServerName site-a.com ServerAlias www.site-a.com DocumentRoot /path/to/www.site-a # Note: SSL settings only need to be defined once! SSLEngine On SSLCertificateFile /path/to/thecert.crt SSLCertificateKeyFile /path/to/thecert.key </VirtualHost> # Not SSL, redirect to https://secure.site-a.com <VirtualHost 192.168.1.200:80> ServerName secure.site-a.com Redirect / https://secure.site-a.com/ </VirtualHost> # https://secure.site-a.com <VirtualHost 192.168.1.200:443> ServerName secure.site-a.com DocumentRoot /path/to/secure.site-a </VirtualHost> # http://test.site-a.com # https://test.site-a.com <VirtualHost 192.168.1.200:80 192.168.1.200:443> ServerName test.site-a.com DocumentRoot /path/to/test.site-a </VirtualHost> # http://www.site-b.com # https://www.site-b.com -- Throws warning because cert is for *.site-a.com <VirtualHost 192.168.1.200:80 192.168.1.200:443> ServerName www.site-b.com DocumentRoot /path/to/secure.site-b </VirtualHost> # Not SSL, redirect to https://secure.site-b.com <VirtualHost *:80> ServerName secure.site-b.com Redirect / https://secure.site-b.com/ </VirtualHost> # https://secure.site-b.com -- Throws warning because cert is for *.site-a.com <VirtualHost 192.168.1.200:443> ServerName secure.site-b.com DocumentRoot /path/to/secure.site-b </VirtualHost>
Despite having a wildcard certificate for *.site-a.com, you will get an invalid domain message when you don’t supply the subdomain (i.e. http://site-a.com). The only way I know of to solve this is with 2 static IPs and 2 certs where one cert is for site-a.com and the other is for *.site-a.com.
I’m using 192.168.1.200 for the server’s IP address behind the firewall. You could try using * instead of 192.168.1.200 in the <VirtualHost> blocks, but I haven’t tested this. Leave a comment if you happen to test this.
Assuming the stars have aligned, you should have several secured virtual hosts!
The “export” command was truncated in the post above. Should have been:
export SAN=’DNS:[base-domain-name]‘
Eg,
export SAN=’DNS:site-a.com’
Comment by Warwick — November 5, 2008 @ 12:38 am
If you want browsers to be happy with the certificate when hitting the base domain (site-a.com), you might want to look at signing the certificate with a subjectAlternativeName set to the base domain as well.
My openssl.conf has “subjectAltName=${ENV::SAN}” in the [ usr_crt ] section, and I set the environment variable (eg “export SAN=’DNS:‘”) before running the openssl commands to create the certificate.
Comment by Warwick — November 5, 2008 @ 12:36 am
I ran into a similar problem just the other day with redirects. Your config looks good. The problem was browser cache. I had to empty my cache and restart my browser and then the redirects worked.
Comment by Chris Barber — February 27, 2009 @ 7:30 pm
I configured my sites-enabled conf like yours, direkt SSL is working fine, but if I go to http://www.domain.com or xyz.domain.com I see a bad request (400) and a redirect to https://domain.com regardless what subdomain I used. (so the redirect is not working and http://www.domain.com didn’t work too) only the direkt SSL will work like https://test.domain.com the wildcard certificate works well with the direkt SSL connection, so it have to be the config :hmm: I’m not sure if the fcgi config have to be on every VirtualHost
1 NameVirtualHost 84.200.208.192:80
2 NameVirtualHost 84.200.208.192:443
3
4
5 ServerName suretodie.de
6 ServerAlias http://www.suretodie.de
7 ServerAdmin admin@suretodie.de
8 DocumentRoot /var/www/web1/web/
9
10
11 SuexecUserGroup web1 web1
12 PHP_Fix_Pathinfo_Enable 1
13
14 Options +ExecCGI
15 AllowOverride All
16 AddHandler fcgid-script .php
17 FCGIWrapper /var/www/php-fcgi-scripts/web1/php-fcgi-starter .php
18 Order allow,deny
19 Allow from all
20
21
22
23 # ErrorLog /var/log/apache2/error.log
24 # CustomLog /var/log/apache2/access.log combined
25 ServerSignature Off
26
27 SSLEngine On
28 SSLCertificateFile /etc/apache2/ssl/suretodie.crt
29 SSLCertificateKeyFile /etc/apache2/ssl/suretodie.key
30
31
32
33 #Redirects
34 # Not SSL, redirect to https://qmail.suretodie.de
35
36 ServerName qmail.suretodie.de
37 Redirect / https://qmail.suretodie.de/
38
39
40
41 ServerName webmail.suretodie.de
42 Redirect / https://webmail.suretodie.de/
43
44
45
46
47 ServerName qmail.suretodie.de
48 ServerAdmin admin@suretodie.de
49 DocumentRoot /var/www/web1/qmailad/
50
51
52 SuexecUserGroup web1 web1
53 PHP_Fix_Pathinfo_Enable 1
54
55 Options +ExecCGI
56 AllowOverride All
57 AddHandler fcgid-script .php
58 FCGIWrapper /var/www/php-fcgi-scripts/web1/php-fcgi-starter .php
59 Order allow,deny
60 Allow from all
61
62
63
64 # ErrorLog /var/log/apache2/error.log
65 # CustomLog /var/log/apache2/access.log combined
66 ServerSignature Off
67
68
69
70 ServerName webmail.suretodie.de
71 ServerAdmin admin@suretodie.de
72 DocumentRoot /var/www/web1/webmail/
73
74
75 SuexecUserGroup web1 web1
76 PHP_Fix_Pathinfo_Enable 1
77
78 Options +ExecCGI
79 AllowOverride All
80 AddHandler fcgid-script .php
81 FCGIWrapper /var/www/php-fcgi-scripts/web1/php-fcgi-starter .php
82 Order allow,deny
83 Allow from all
84
85
86
87 # ErrorLog /var/log/apache2/error.log
88 # CustomLog /var/log/apache2/access.log combined
89 ServerSignature Off
90
Comment by hackbard — February 27, 2009 @ 5:00 pm
sry for that copy crap, here is a better pastebin
http://pastebin.com/m5a3d5201
you can delete my other post
“I configured my sites-enabled conf like yours, direkt SSL is working fine, but if I go to http://www.domain.com or xyz.domain.com I see a bad request (400) and a redirect to https://domain.com regardless what subdomain I used. (so the redirect is not working and http://www.domain.com didn’t work too) only the direkt SSL will work like https://test.domain.com the wildcard certificate works well with the direkt SSL connection, so it have to be the config :hmm: I’m not sure if the fcgi config have to be on every VirtualHost”
greets hackbard
Comment by hackbard — February 27, 2009 @ 5:12 pm
Hi Chris!
I checked it with deleted cache in IE and Firefox, the same as before. With the IE nothing is shown, no error, no redirect, no index :hmm:
In firefox the same as belwo shows up.
I don’t get whats wrong :hmm:
my second domain shows the same error in FF, “go to https://suretodie.de”
:hmm:²
Comment by hackbard — March 2, 2009 @ 10:13 am
I think I’ve got it. I splittet up the first vhost entry like this:
http://pastebin.com/m3eceb493
After that the bad Requests gone away and the little Indian Apache works.
Thx for your help and config.
Greetz hackbard
Comment by hackbard — March 5, 2009 @ 9:35 am
Hmm, well, that was easy. Good thinking!
Comment by Chris Barber — March 5, 2009 @ 4:52 pm