Home » Forcing SSL on a subdomain

Forcing SSL on a subdomain

April 9th, 2006 by Jim

It is common to create a subdomain named secure.domain.com, and then purchase (or self-sign) a SSL certificate to go with it. The intention is that visitors will see the word “secure” and feel better knowing that a secure communication channel is being used. Not everyone knows what the acronym SSL means, after all.

Simply having an appropriate host name does nothing to enforce the concept, though. The subdomain intended for SSL connections should not be accessed any other way, and likewise all other subdomains should disallow SSL connections.

With Apache + mod_rewrite, we can…

  • Force secure.domain.com to only allow SSL connections.
  • Force https://anything_else.domain.com to redirect to https://secure.domain.com.

Note: It is assumed that your Apache setup consists of two virtual hosts: one for domain.com:80 and one for domain.com:443 (SSL-enabled). This is how most website control panels configure a site. Unfortunately, the control panels also configure a site’s subdomains so they are accessable on both port 80 and port 443, which is basically what we are trying to work around.

Rules for the non-SSL virtual host (port 80)

RewriteEngine on
RewriteCond   %{HTTP_HOST} ^secure.domain.com$         [NC]
RewriteRule   ^(.*)$       https://secure.domain.com$1 [R,L]

Rules for the SSL-enabled virtual host (port 443)

RewriteEngine on
RewriteCond   %{HTTP_HOST} !^secure.domain.com$        [NC]
RewriteRule   ^(.*)$       https://secure.domain.com$1 [R,L]

If mod_rewrite is out of the question, it is possible to simulate the same effect in code. This method uses a HTTP 302 redirection (just like mod_rewrite), so it is very important to call this script before any output is sent to the browser.

Using PHP

// Before any output, preferably as the first line in the script...
if
(   (   $_SERVER['HTTP_HOST'] == 'secure.domain.com' &&
        $_SERVER['HTTPS'    ] == '' // (non-SSL)
    )
    ||
    (   $_SERVER['HTTP_HOST'] != 'secure.domain.com' &&
        $_SERVER['HTTPS'    ] != '' // (SSL-enabled)
)   )
{
// Redirect...
    header('Location: https://secure.domain.com'.$_SERVER["PHP_SELF"]);
    exit(0);
}

Leave a Reply »

One Response to “Forcing SSL on a subdomain”

  1. Chris Martin Says:

    Nice job. This is a very concise way to acheive something that on the surface appears a bit challenging using simple applied logic.