SSL Part 1: Multi-Websites 1

From The Uniform Server Wiki
Jump to navigation Jump to search

MPG UniCenter

SSL Part 1 Extra: Home | Multi-Websites 1 | Multi-Websites 2 | Debug VHost

mod_ssl Multi-Websites 1
Uniform Server 3.5-Apollo

Securing multi-websites using virtual hosts on a single IP address.

The problem with trying to secure name-based virtual hosts lies in the protocols used. When a browser sends an SSL request the server sends the SSL certificate before it deals with which URL is requesting a secure connection. Hence if you are using virtual hosts for hosting several sites on one IP address you receive the same certificate for each site. This results in the browser issuing a domain name certificate mismatch alert.

For a personal secure server it’s an annoyance. Two alert messages are displayed, certificate cannot be verified (self-signed certificate) and the domain site mismatch. A connection when established is secure (in terms of encryption and decryption) it just does not look professional. This write-up looks at ways to remove the second irritation (domain site mismatch) we will live with the first unless you want to part with some cash.

Note: Check out my Signed Certificate Project to obtain a free server certificate from CAcert.

Template modification

Before looking at details I assume you have the template up and running and you have obtained a domain name say from DynDNS (I will be using unicenter.gotdns.org).

Note: You will find support folders and files in folder *\Uniform Server\udrive\www\test_multi

First copy the three new root folders site4, site5 and site6 to folder www. These each contain an index page and a favicon.ico image (prevents error messages in the log files).

For our tests the main Apache configuration file httpd.conf will not change.

However you will be editing the ssl.conf file to save typing I have included examples in folder test_multi these are named ssl.conf1.txt, ssl.conf2.txt and ssl.conf3.txt. Each file has been reduced to the bare minimum.

Preparation

Copy ssl.conf1.txt to folder *\Uniform Server\udrive\usr\local\apache2\conf and rename it to ssl.conf (first either delete the original or save to a different folder)

View this file, I have highlighted changes in bold:

NEW Comments

#################### Global SSL ######################## Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog builtin
SSLSessionCache shmcb:logs/ssl_scache(512000)
SSLSessionCacheTimeout 300
SSLMutex default
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

The first line instructs Apache to listen on port 443 (standard secure port) you can change this to a different port, remember to change other sections to match. If you run each Vhost on a separate port add a corresponding listening statement here.

########### SSL Virtual Host ############################

NameVirtualHost *:443

This instructs Apache the following Vhost block or blocks are associated with any IP address (* wildcard) on port 443. You can define a new Vhost block or blocks on a different port number, remember that it is the start of a new section hence will require its own NameVirtualHost statement.

<VirtualHost *:443>
  ServerName default.unicenter.gotdns.org
  DocumentRoot /www/default_secure
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
</VirtualHost>

This is our first virtual host, not really used for serving a website just a single default page. The server name is strictly not required this Vhost is being used only as a default block. Apache searches all Vhost's in a section if it cannot find a match will always use the first one defined within the appropriate section.

A single page is servered from the root folder default_secure. This way of implementing the default is a personal preference you can use whatever is appropriate.

<VirtualHost *:443>
  ServerName site4.unicenter.gotdns.org
  DocumentRoot /www/site4
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
</VirtualHost>

First real hosted site. Each VirtualHost has *:443 to instruct Apache they are associated with any IP address on port 443.

Note: site4 is the wildcard portion of my domain name unicenter.gotdns.org if this is matched Apache it will serve pages from the root folder /www/site4

<VirtualHost *:443>
  ServerName site5.unicenter.gotdns.org
  DocumentRoot /www/site5
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
</VirtualHost>

Second real hosted site.

Note: site5 is the wildcard portion of my domain name unicenter.gotdns.org its quite imaginative! Your real site would use something more appropriate for example news or info.

If I was not interested in portability there is no real reason to have my root folder located where it currently is. I could have my website located on drive D in folder info and instruct Apache to server pages from it using DocumentRoot D:/info

<VirtualHost *:443>
  ServerName site6.unicenter.gotdns.org
  DocumentRoot /www/site6
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
</VirtualHost>

Last real hosted site.

Top

Test

Save the file, restart your servers and run the following tests, note the results:

  1. Type https://site4.unicenter.gotdns.org/ into your browser
  2. Type https://site5.unicenter.gotdns.org/ into your browser
  3. Type https://site6.unicenter.gotdns.org/ into your browser
  4. Type https://fred.unicenter.gotdns.org/ into your browser

In test 1 you will receive two moans from your browser the first being the certificate cannot be verified secondly a domain mismatch.

In test 2-4 you will only receive the domain mismatch alert.

Note: Before repeating a test always re-start your browser (clears the sessions)

Top

Wildcards

Our first experiment looks at wildcard certificates. If we can create one of these, it will match any of our sub-domains. Sounds complicated in reality all you need to do is add * to your domain name when creating a certificate:

Create the wildcard certificate as follows:

  1. Stop servers
  2. Navigate to folder *\Uniform Server\udrive\home\admin\www\plugins\uc_mod_ssl\key_cert_gen
  3. Double click on clean.bat - Removes old files
  4. Double click on mpg1.bat --- fill in details -- To use defaults Press enter
  1. Enter PEM pass phrase:fred
  2. Verifying - Enter PEM pass phrase:fred
  3. Country Name (2 letter code) [GB]: Press enter
  4. State or Province Name or County (full name) [Cambridgeshire]: Press enter
  5. Locality Name (eg, city or town) [Cambridge]: Press enter
  6. Organization Name (eg, company) [Unicenter]: Press enter
  7. Organizational Unit Name (eg, section) [Demo Example Mike Gleaves]: Press enter
  8. Common Name (eg, your websites domain name) []: *.unicenter.gotdns.org
  9. Email Address []: Press enter
  10. A challenge password []: Press enter
  1. Double click on mpg2.bat --- When requested enter pass phrase fred
  2. Double click on mpg3.bat --- Creates the certificate
  3. Copy file server.key to folder *\Uniform Server\udrive\usr\local\apache2\conf\ssl.key
  4. Copy file server.crt to folder *\Uniform Server\udrive\usr\local\apache2\conf\ssl.crt

It really is that easy.

Top

Test

Save the file, restart your servers and run the following tests, note the results:

  1. Type https://site4.unicenter.gotdns.org/ into your browser
  2. Type https://site5.unicenter.gotdns.org/ into your browser
  3. Type https://site6.unicenter.gotdns.org/ into your browser
  4. Type https://fred.unicenter.gotdns.org/ into your browser
  • In test 3 you will receive one alert the certificate cannot be verified.
  • In test 3-6 the certificate matches all our sub-domains hence no alerts.

Top

Results

Results: YES = An alert produced NO = No alert produced

  IE 6 Opera 9 Firefox 2.0
   Certificate not verified   Domain mismatch   Certificate not verified   Domain mismatch   Certificate not verified   Domain mismatch 
 Test 3  YES NO YES NO YES NO
 Test 4  YES NO YES NO NO NO
 Test 5  YES NO YES NO NO NO
 Test 6  YES NO YES NO NO NO

I must confess to being surprised at the results, the depth of sub-domain naming (site6.unicenter.gotdns.org) I expected IE6 to fail and the other two would pass because they are newer browsers.

Of the browsers Firefox is neat and logical it alerts you once to the fact this certificate cannot be verified.


Top

Password Protection

A personal web server can take advantage of a secure link, and use basic authentication. There is no need for the added complexity of encrypting names and passwords to a file.

If the following meets your requirements use it, I offer this only because I have been asked several times, Uniform Server offers a reasonable safe bucket to place your passwords. I say reasonable because the design team have no idea where you will place this bucket and who will have physical access to your machine.

Define who has access

We have three sites to protect, names and passwords are sent over the Internet using SSL hence we safe and protected from outside sniffers . The first two sites (4 and 5) shall be accessible only by their owners. The third site shall be accessible by the three site owners.

A little contrived! I know, but it helps to demonstrate what you can do with basic authentication.

Preliminary

Create password files:

In folder *\Uniform Server\udrive\htpasswd create three new folders named modssl_site4, modssl_site5 and modssl_site6.

Into each of these copy the file .htpasswd (contained in folder *\Uniform Server\udrive\htpasswd\modsslpass )

Edit each file in turn, add the name/password pairs that you wish to use for example:

modssl_site4\.htpasswd modssl_site5\.htpasswd modssl_site6\.htpasswd

mike:enter123

john:passweek

mike:enter123
john:passweek
ric:unicenter

One point worthy of note, a password file may contain a list of name/password pairs.

Top

Modify the ssl.conf file

Each Vhost requires a basic authentication block, alternatively you could use a .htaccess file placed in each root folder. The block has the following format:

#== Basic authentication  
<Directory "/www/site5"> Path of the folder that is to be protected (Not required in a .htaccess file)
  AuthName "Uniform Server - Demo Server Access" This string is displayed in the pop-up box
  AuthType Basic Authentication type basic or digest we are using basic
  AuthUserFile /htpasswd/modsslpass/.htpasswd Path and name of the password file
  Require valid-user A valid user name and password must be enter to gain access to this folder
</Directory> Not required in a .htaccess file

Open ssl.conf (*\Uniform Server\udrive\usr\local\apache2\conf) and add the authentication blocks. Alternatively copy file ssl.conf2.txt from folder \www\test_multi rename it ssl.conf edit to your specific requirements.

Your file will look similar to this:

  New  

#################### Global SSL ########################
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog builtin
SSLSessionCache shmcb:logs/ssl_scache(512000)
SSLSessionCacheTimeout 300
SSLMutex default
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

########### SSL Virtual Host ############################
NameVirtualHost *:443

<VirtualHost *:443>
  ServerName default.unicenter.gotdns.org
  DocumentRoot /www/default_secure
  SSLEngine on
  SSLCipherSuite  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
</VirtualHost>

<VirtualHost *:443>
  ServerName site4.unicenter.gotdns.org
  DocumentRoot /www/site4
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
#== Basic authentication
 <Directory "/www/site4">
  AuthName "Unicenter Demo - Site 4 Access"
  AuthType Basic
  AuthUserFile /htpasswd/modssl_site4/.htpasswd
  Require valid-user
 </Directory>
</VirtualHost>

<VirtualHost *:443>
  ServerName site5.unicenter.gotdns.org
  DocumentRoot /www/site5
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
#== Basic authentication
 <Directory "/www/site5">
  AuthName "Unicenter Demo - Site 5 Access"
  AuthType Basic
  AuthUserFile /htpasswd/modssl_site5/.htpasswd
  Require valid-user
 </Directory>
</VirtualHost>

<VirtualHost *:443>
  ServerName site6.unicenter.gotdns.org
  DocumentRoot /www/site6
  SSLEngine on
  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  SSLProtocol all -SSLv2
  SSLCertificateFile conf/ssl.crt/server.crt
  SSLCertificateKeyFile conf/ssl.key/server.key
#== Basic authentication
 <Directory "/www/site6">
  AuthName "Unicenter Demo - Site 6 Access"
  AuthType Basic
  AuthUserFile /htpasswd/modssl_site6/.htpasswd
  Require valid-user
 </Directory>
</VirtualHost>


Top

Test

Run the test using your own domain name, enter name and password when challenged.

  1. Re-start browser
  2. Re-start Servers
  3. Type https://site4.unicenter.gotdns.org/ into your browser
  4. Type https://site5.unicenter.gotdns.org/ into your browser
  5. Type https://site6.unicenter.gotdns.org/ into your browser
  6. Type https://fred.unicenter.gotdns.org/ into your browser
  • In test 3 you will receive one alert the certificate cannot be verified.
  • In test 3-6 the certificate matches all our sub-domains hence no alerts.

Summary

I prefer the above method however there are several ways to accomplish multi-site hosting on the next page I look at an alternative method.

Top


Ric