Stunnel: Single Vhost

From The Uniform Server Wiki
Jump to navigation Jump to search

MPG UniCenter

Stunnel: Home | Upgrade 4.24 | Install | SSL Certificate | Single Vhost | Resolved | Basics | Cost | Original

Stunnel securing a single virtual host
Uniform Server 3.5-Apollo

Uniform Server’s default Stunnel installation secures the entire server or does it? I have had several emails stating that Stunnel does not secure the server because the server contents are accessible by both http (port 80) and https (port 443).

That’s true however using https any data entered into a form are encrypted before being sent over the Internet, which is the whole point of a secure link. In addition page content is also encrypted.

Problem

After several emails I finally discovered what was required. They were running several virtual hosts and wanted a single host to be secure. Further they wanted to freely switch between secure and non-secure with the same domain name displayed.

Solution

Stunnel like Apache (mod_ssl) can only secure one virtual host and is relatively easy to implement, splitting a domain name into secure and non-secure parts is the main problem area. The solution is to use port based virtual hosting this allows you to use ports as selectors for separation. The following explains this proposed solution, its not intended for a production server however for a personal server should be more than adequate.

Top

Stunnel and Headers

Stunnel connects one port to another effectively acting as a port translator. One side of Stunnel is encrypted and the other decrypted more importantly for this solution it does not mangle header information; hence all information is routed from one port to another.

The significance of this, Apache can separate out any domain name on any port using virtual hosts. The standard (non-secure) listening port is port 80. However Apache can listen on as many ports as we like which we use to our advantage. This solution uses port 8080 (only because its an easy number to remember) you may need to change this if it clashes with another application you are running.

Top

Stunnel Config

Open stunnel.conf located in folder *\Uniform Server\udrive\home\admin\www\plugins\stunnel_424\bin and change the default connect port to 8080 (or use an alternative)

Default New Encrypted Data User B

[uniform35]
accept = 443
connect = localhost:80

[uniform35]
accept = 443
connect = 8080

Port 443 is the standard secure port for https
We are translating this port to 8080.

Firewall

Open up your firewall and or router make sure you deny external access to port 8080 this prevents anyone viewing the secure part of your site on a non-secure connection (when using http://). See previous page for details.

Stunnel PEM file

If this is a new installation of Stunnel create a new Stunnel PEM (self-signed certificate ) for your site, if you like you can use the existing one included in the download for testing, remember to create a new certificate. The PEM file contains your secret key hence the default has been rendered useless due to the fact anyone can download the files and retrieve this key.

To create a new key see previous page for details.

If its not a new installation and you have already created your PEM you can continue to use it, its unique to you.

Top

Virtual host errors

Before looking at the Apache configuration thought I would confess to a lack of understating of virtual host. This was brought home to me when I noticed these warnings and errors in the Apache error log:

[warn] default VirtualHost overlap on port 8080, the first has precedence
[error] mixing * ports and non-* ports with a NameVirtualHost address is not supported

I like to group common elements together however the above error was generated because of this practice. I originally had these two lines followed by all the virtual host sections

NameVirtualHost *:80
NameVirtualHost *:8080

I thought these were general statements and could be grouped together however it turns out they are block statements. Hence what follows each statement (block) must be related.

Top

Correct Virtual Host sequence

To show you what I mean, here is a cut down version of the virtual host section with listening statements added.

Commands Comments

Listen 80
Listen 8080

These can be grouped hence add Listen 8080 below Listen 80 in the config file around line 125

NameVirtualHost *:80

Defines a block of virtual hosts associated with port 80 they can have any domain name indicated by the *

<VirtualHost _default_:80>
  DocumentRoot /www/default_notsecure
</VirtualHost>

If Apache cannot find a matching site as requested by a user on port 80 it will display this site by default. The default is always the first one in a virtual host list, normally a single page will do. Make the page content general and none descript, remember any user can come across this page by mistake! Or perhaps we have screwed up badly.

Note: By using _default_ a ServerName directive is no longer required it also prevents Apache serving pages from our main server.

<VirtualHost *:80>
  ServerName fred.gotdns.com
  DocumentRoot /www/site1_unsecure
</VirtualHost>

This is the first real virtual site coincidentally it is the one we wish to partially secure however this section is un-secured. It can be placed anywhere in the virtualhost list.

<VirtualHost *:80>
  ServerName cars.dyndns2.com
  DocumentRoot /www/cars
</VirtualHost>

A second virtual site again its public and not secured, add as many sites to this section that you will be hosting.

Note 1: If you use admin panel to add virtual sites it saves a little bit of typing however you will need to edit the resulting config file.
Note 2: Each site that does not correspond to your secured site needs to be moved under this section and the * replaced with *:80

NameVirtualHost *:8080

Defines a block of virtual hosts associated with port 8080 they can have any domain name indicated by the * this block must contain only two virtual hosts.

<VirtualHost _default_:8080>
  DocumentRoot /www/default_secure
</VirtualHost>

If Apache cannot find a matching site as requested by a user (secure port 443 remapped to port 8080) on port 8080 it will display this site by default. The default is always the first one in a virtual host list, normally a single page will do. Make the page content general and nondescript, remember any user can come across this page by mistake! Or perhaps we have screwed up badly.

Note 1: By using _default_ a ServerName directive is no longer required it also prevents Apache serving pages from our main server.
Note 2: One minor irritation, a browser will warn users a certificate is invalid before the default page is displayed.

<VirtualHost *:8080>
  ServerName fred.gotdns.com
  DocumentRoot /www/site1_secure
</VirtualHost>

This is the last virtual site in this section (for port 8080). It corresponds to the unsecured portion (for port 80) of our partially secured site. Stunnel accesses this unsecured virtual host and secures it.

The above I admit was conservative with the truth, it is the full solution and not a cut down version. NOW’s a good time to go back and have another read just to see what you have missed! The following provides a few more details.

Top

Sites

The main root folder www contains the following site root folders.

Main Root Folder www Comments

default_notsecure

Contains a single index.html page this is descriptive for all non secured sites hosted. A user can mistype an address name hence may reach this page by mistake

default_secure

Contains a single index.html page this is descriptive for all secured sites hosted. There is only one site, however a user can mistype an address name hence may reach this page by mistake.

site1_unsecure

This is the unsecured site it shares the common host name fred.gotdns.com

site2 site3 site4 siten

More virtualhost sites.

site1_secure

This is the unsecured site being secured using Stunnel it shares the common host name fred.gotdns.com.

There are no restriction on folder names choose whatever you like. I avoid names with spaces, some FTP programs fall over when they come across these. You can if you wish use the main root folder www as default however my personal preference is to have separate folders and never serve from main root.

Browser Access

To access the non secure portion of your site a user would type http://fred.gotdns.com

To access the secure portion of your site a user would type https://fred.gotdns.com

(Obviously substitute fred.gotdns.com for your real domain name)

Top

Password protection

In this document I have been using the term secure to refer to data sent over the Internet in an encrypted form. The server remains open to public access however you may wish to authenticate access by using a name and password.

You can use Apache's basic authentication to password protect access to the secure area, however from a users point of view it appears both name and password are sent in plain text (lock icon shows open). In actual fact the handshake process has been completed and encrypted communication established before the name and password are sent. The lock only toggles to the locked position when the first part of the actual web page data is transferred. If you are happy with this you can use the existing Uniform Server password file. Alternatively create a new password file.

Note: Windows XP will not allow you to copy and rename the file .htpasswd which is located in folder *\Uniform Server\udrive\htpasswd\www. To Windows the file looks like a file extension (because of the full stop) if you try to rename it Windows insists you add a filename!

Instead open the file in a text editor add the new name and password save the file say as .newpass1 The file looks similar to this substitute your real name and password that you want to use.

.newpass1

john:doe123

Now copy an existing .htaccess file (just saves a little typing) to folder site1_secure and change it to this:

# This file provides security to the server limiting access to the localhost only.
# Comment to deactivate.

#Order Deny,Allow
#Deny from all
#Allow from 127.0.0.1

# To allow execution of cgi scripts in this directory uncomment next two lines.

AddHandler cgi-script .pl .cgi
Options +ExecCGI

#--
# Activate this to use the Private Server Feature!
#--
# To lock server, uncomment the next 4 lines.
# Defaults: Username - root; Password - root

AuthName "Uniform Server - Server Access"
AuthType Basic
AuthUserFile /htpasswd/www/.newpass1
Require valid-user

Top

Paranoid - Protect each page

As mentioned above using Apache’s basic authentication gives a user the impression that both name and password are sent unencrypted. The padlock only synchronises to the closed position on receiving the first part of a web page.

An alternative to using basic authentication is to search the Internet for scripts that password protect pages, there are hundreds of these PHP scripts. Stunnel encrypts your pages hence any protection used name/passwords will inherently be encrypted by Stunnel.

To save you some legwork I found this script Page Password Protect 2.13


Alternatively go to http://www.zubrag.com/ and download the latest version of Web Page Password Protect. Please note my write-up is for version 2.13 hence there may be small differences.

It really is an easy script to use, ideal for demonstrating the concept of page authentication over Stunnel, which serves my purpose admirably.

  1. Save the file ucPasswordProtect.exe to any location.
  2. Double click on this file to run the self-extracting utility.
  3. In the folder extracted password_protect you will find a file named password_protect.php copy this file to folder site1_secure (your secure folder).

Top

Setup

Open the file password_protect.php add names and passwords that you are going to use. I have show the relevant section below:

# SETTINGS START
##################################################################

// Add login/password pairs below, like described above
// NOTE: all rows except last must have comma "," at the end of line
$LOGIN_INFORMATION = array(
'root' => 'root',
'mike' => 'fred123'
);

// request login? true - show login and password boxes, false - password box only
define('USE_USERNAME', true);

The file is self-documenting hence read the comments; you can change the page if you wish to match your web site. I have not butchered the page in anyway it remains as downloaded. After setting up your names and passwords save the page.

Each page you are going to protect (must have the file extension .php) requires one line of code adding to the top of each page.

To obtain this information run the page password_protect.php?help from you server (both Apache and Stunnel running) for example

https://fred.gotdns.com/password_protect.php?help

You will see a line similar to this displayed which you add to each page:

<?php include("W:\\www\\site1_secure\\password_protect.php"); ?>

One small mod to the line

The script is general purpose hence the method of obtaining a path to the file. Since we are running our own server there is no real need to use this method. The file * is an include file and we know where we placed it, in addition we know where to start looking (top of the drive where Apache is running) hence no need to specify a drive letter. The line effectively becomes this just use your real folder names where appropriate:

<?php include("\\www\\site1_secure\\password_protect.php"); ?>

Top

Prevent Folder (Directory) listing

You may want to prevent directory listings (for folders that do not contain an index file) modify the .htaccess file in site1_secure to look like this:

# This file provides security to the server limiting access to the localhost only.
# Comment to deactivate.

#Order Deny,Allow
#Deny from all
#Allow from 127.0.0.1

# To allow execution of cgi scripts in this directory uncomment next two lines.

AddHandler cgi-script .pl .cgi
Options +ExecCGI

#--
# Activate this to use the Private Server Feature!
#--
# To lock server, uncomment the next 4 lines.
# Defaults: Username - root; Password - root

# AuthName "Uniform Server - Server Access"
# AuthType Basic
# AuthUserFile /htpasswd/www/.newpass1
# Require valid-user

IndexIgnore *

Its not absolutely necessary but adding the line IndexIgnore *prevents directory listings.

I have shown one script you can use for name/password protection try some others its always worth looking at new code.

One final point

Once you have set up the servers remember to do a bit of port bashing as explained on the previous page, enjoy.

Conclusion

I once asked myself the question “why do I support Uniform Server”? Well if you have read this article one thing is clear, it is easy to tailor and change to meet a specific requirement. Overall I find it logically constructed and extremely accessible, it’s a perceived simplicity and that’s a real credit to the design team.

Back to Stunnel, don’t be intimated by the techno stuff go in and have a play. If you break it, load up another copy and hack it some more.

Top


Ric