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!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Reddit

8 Comments »

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  7. 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

  8. Hmm, well, that was easy. Good thinking!

    Comment by Chris Barber — March 5, 2009 @ 4:52 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment