Web Hosting Talk







View Full Version : How to set up SSL on a name-based virtual host on a RaQ4


Bruce Coble
12-02-2002, 06:42 PM
Hi there everyone...I've wasted weeks on this one, & now that I've got it working, I thought I'd share the answer...

As the chief web developer in our company, I've taken over administering a RaQ4, after the chap who bought it left the company...ie, I'm a novice when it comes to setting up web servers. When I saw the RaQ, I thought, "Great - a web server in a box". We currently have one IP & a number of name-based virtual-host domains setup which use that IP.

I wanted to test an intranet I'd been working on, so I switched on SSL for one host domain, typed https://mydomain.com.au & saw that SSL was working fine...then I typed http://mydomain.com.au - & I SAW THE SAME PAGE WITHOUT SSL :eek: :confused: :angry:

It's not what I'd call particularly smart design :stickout:

(Before I launch into my explanation, a note for the uninitiated here: RaQs will only let you have SSL on ONE name-based virtual-host domain per IP address...)

So here's what I did to get SSL only on a name-based virtual-host domain:

1. Create the domain you wish to make your secure domain using the GUI.

2. Switch on SSL in the admin GUI

3. Add the certificate in the admin GUI

4. Open your httpd.conf file (mine was in /etc/httpd/conf/httpd.conf)

5. At this section:
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the VirtualHost command

Listen 80

add this:

Listen <<MyIPAddressHere>>:443

6. At this section :

# O.K. What we bassically want to do is build up new section in the conf file
# for SSL sections.


comment out the while statement that follows like so:

#while(<HTTPD_CONF>) {
# if (/^<VirtualHost [\d\.]+>$/ ... /^<\/VirtualHost>$/) {
# if ( /^<VirtualHost ([\d\.]+)>/o ) {
# # New section. Clean up.
# $ip = $1;
# @ssl_conf = ();
# $group = undef;
# }
#
# # Skip this bit, we don't need it now..
# next if (/^<VirtualHost/);
#
# # Just need to grab the group name out before we get on with
# # the real work.
# if ( /DocumentRoot \/home\/sites\/([^\/]+)\/web/ ){
# $group = $1;
# }
#
## # These two are for the rewrite options
# s/http/https/go if (/^Rewrite/);
# s/80/443/go if (/^Rewrite/);
# push @ssl_conf, $_;
#
# # Hardcoded, issues with mod_perl and cobalt modules.
# if (/^<\/Virtual/ and (-f "/etc/httpd/ssl/$group")) {
# $ret = ssl_cert_check("/home/sites/$group/certs/");
# if ($ret=~/^2/o) {
# $PerlConfig .= "Listen $ip:443\n";
# $PerlConfig .= "<VirtualHost $ip:443>\n";
# $PerlConfig .= "SSLengine on\n";
# $PerlConfig .= "SSLCertificateFile /home/sites/$group/certs/certificate\n";
# $PerlConfig .= "SSLCertificateKeyFile /home/sites/$group/certs/key\n";
# $PerlConfig .= join('', @ssl_conf);
# } elsif (ssl_cert_check("/home/sites/home/certs/") =~ /^2/ ) {
# $PerlConfig .= "Listen $ip:443\n";
# $PerlConfig .= "<VirtualHost $ip:443>\n";
# $PerlConfig .= "SSLengine on\n";
# $PerlConfig .= "SSLCertificateFile /home/sites/home/certs/certificate\n";
# $PerlConfig .= "SSLCertificateKeyFile /home/sites/home/certs/key\n";
# $PerlConfig .= join('', @ssl_conf);
# } else {
# print STDERR "Site $group has invalid certificate: $ret\n";
# }
# }
# }
#}
close HTTPD_CONF;


and now the important stuff,

7. Go to the virtual host directive for the domain that you wish to isolate for SSL, & change it to look like this (replace X with your domain's site number):

<VirtualHost MyIPAddress:443>
ServerName mydomain.com.au
ServerAdmin admin
DocumentRoot /home/sites/siteX/web
ServerAlias mydomain.com.au
SSLengine on
SSLCertificateFile /home/sites/siteX/certs/certificate
SSLCertificateKeyFile /home/sites/siteX/certs/key
AliasMatch ^/~([^/]+)(/(.*))? /home/sites/siteX/users/$1/web/$X
AliasMatch ^/users/([^/]+)(/(.*))? /home/sites/siteX/users/$1/web/$X
TransferLog /home/sites/siteX/logs/access_log
ErrorLog /home/sites/siteX/logs/error_log
AddHandler cgi-wrapper .cgi
AddHandler cgi-wrapper .pl
AddHandler server-parsed .shtml
AddType text/html .shtml
</VirtualHost>

Now if someone tries to access https://mydomain.com.au, they will go through SSL. But if someone goes to http://mydomain.com.au, they will be redirected to
the first domain that appears in your list of virtual host directives...

8. Now that may not be what you want...to alter that, leave your original Virtual Host Directive in the script with <VirtualHost MyIPAddress:80> at the top instead (also, make sure you leave in all of the rewrite rules that I took out for the SSL version above). Then just change the document root directive to specify where you want people to be redirected if they do type http://mydomain.com.au (perhaps a nice error message page on another non-SSL domain :stickout: )

Hope that helps someone out...

I'm sure that the perl script commented out in section 6 of my explanation is supposed to do something like this, & maybe my approach is the sledgehammer technique...if there are any Perl experts (PHP is my thang) who could suggest a less intrusive alternative (or anyone else for that matter), your thoughts would be welcome on this one. I'm a web server newbie, who knows one thing for sure: I know a lot of things, but there are more things in this world to know than I could possibly know myself (that's why we share our grey matter in wonderful forums such as this :cool: ).

Keep the good stuff coming :D

BruceT
12-03-2002, 08:09 PM
Just a clarification -- the SSL requirement of a unique IP address is not a "Cobaltism" - it's the way the HTTP handshake works. The SSL info is passed around first, before the info on the hostname is.

Also, by commenting out that big block of 'code', the UI might behave unpredictably when adding new virtual sites, or modifying existing ones...

There isn't really a good way to do what you want; I've seen most people make two separate hosts and have one just for secure traffic, and the other for regular...

chirpy
12-04-2002, 12:26 PM
There's also an easy way to restrict access to the SSL site only using mod_rewrite in a .htaccess file instead of messing around with your httpd.conf:

1. Create a .htaccess at the top of the website (i.e. /home/sites/sitennn/web/.htaccess)

2. Add the following to it:

SSLRequireSSL
RewriteEngine on
RewriteBase /home/sites/sitennn/web
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [L,R]

Any requests comming into the site not on port 443 are redirected to the same URL but via the https:// url

Bruce Coble
12-04-2002, 08:02 PM
Appreciate the warning about the UI BruceT.:eek:

And Chirpy, thanks for the suggestion - that does look a whole lot neater;) I'll try that approach out instead:D