I.T. Security and Linux Administration

Mar 29 2011   10:56PM GMT

Enable HTTPS By Default

Eric Hansen Eric Hansen Profile: Eric Hansen

With the recent issues of Microsoft removing HTTPS from Hotmail in some countries, and Comodo’s recent SSL breach, the end users of various software (web and non) should really start considering how secure their data truly is. In the first article, it’s also reported that Yahoo only uses HTTPS for the initial log in process, unless you’re a paying customer. In my view, this is not acceptable practice…why pay to be secure?

Essentially, what I’m going to be bringing up in this post is enabling HTTPS by default (i.e.: forcing HTTPS) via your web server. This will be done via both Apache, Lighttpd, as well as PHP. If you use LiteSpeed, or some other web server, then these steps should still apply to you, but some modifications might have to be made. Please note that this assumes you already have HTTPS set up (enabled for the server, certificates made, etc…). I’ll go over how to do this in a later article, but to make things easier, assumptions are made here. First, we’ll handle this with Lighttpd, as I already set this up for personal projects.

HTTPS in Lighttpd

This will be for your entire server (not just a specific domain, like secure.example.com), so if you do want this only for a certain portion of your hosting, you’ll have to place it in the proper config block. First, open up your config file, and put the following in there (unless it’s for a specific domain, I always add changes to the end):

$HTTP["host"] =~ "secure.example.com" {
$SERVER["socket"] == ":80" {
url.redirect = ( "^/(.*)" => "https://secure.example.com/$1" )
server.name                 = "secure.example.com"

$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/path/to/pem/file/for/example.com"
server.document-root = "/path/to/web/files/for/example.com/"

In actuality, you don’t need the $SERVER[“socket”] == “:80” { … } case statement, but it’s there to reduce the load and redundancy on the server (why constantly force HTTPS if it’s already enabled?). Taken from the Lighttpd Wiki on how to do this, you can also set it up globally like this:

$SERVER["socket"] == ":80" {
$HTTP["host"] =~ "(.*)" {
url.redirect = ( "^/(.*)" => "https://%1/$1" )

HTTPS with Apache (without mod_rewrite)

Personally, I think mod_rewrite is a pain to use in Apache, but it’s also very robust, so it’s kind of a double-edged sword. Since I don’t personally use Apache, I can only go by what experience I had doing this at my last place. But, I’ll show the easy (this), and hard (using mod_rewrite) way. First, it’ll be the easy, but not very robust, way of doing this:

Open up your config file (httpd.conf by default), and put this in near the end:

Redirect permanent / https://secure.example.com/

Doing this is a bit finicky, as sometimes Apache will decide it doesn’t like the “/” at the end of the URL, for example. But, this will redirect all of your traffic that Apache handles to HTTPS. This pretty much tells the browser the HTTP code is 301 (which pretty much just tells the browser not to bother doing anything with the URL but redirect it to https://secure.example.com/).

HTTPS with Apache (with mod_rewrite)

Not everyone has the ability to use mod_rewrite, but if you do, then .htaccess is your best friend here. This is essentially the same as the above Lighttpd step, but it’s not in the configuration file itself. Basically, create a .htaccess file in the directory you want to have HTTPS-only access of, and put this in it:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/(.*) https://secure.example.com/$1 [R]

In short, it tells Apache we’re using mod_rewrite (RewriteEngine On), and checks to see if HTTPS is not being used (RewriteCond %{HTTPS} off). If the condition is meant (accessing the domain using HTTP), then it rewrites/redirects the user to the HTTPS form. If you want this globally, or if you have multiple domains pointing to the same path, just replace “secure.example.com” with %{HTTP_HOST}. The $1 after that is anything you see after the “secure.example.com/” part (i.e.: index.php, contacts.php?user=awesome, etc…). Lastly, if this is the last (or only) rewrite rule in the .htaccess file, then replace “[R]” with “[L,R]” (without quotes). The “L” designates the last rule, and “R” designates it’s a redirection rule. mod_rewrite is a very powerful tool in Apache, and I might do a write up on it in the future, after I brush off my rusty Apache skill set.

PHP Redirect

This last trick is nothing special, and there’s millions (almost literally) of ways to do this in PHP alone, let alone other languages. Usually on my sites I design, I give the user to force SSL when they’re logged in. Then, the page header will always check to see if the user is browsing in HTTPS; if they aren’t, then it redirects using the header() function. Please note that in order for this to work, the code has to be above the tag, and any other code that will put out text (see PHP’s header() function for more information). But, here’s the simple code I use on my sites:

if(!$_SERVER['HTTPS']) && $_SESSION['force_https']){
header("Location: https: //secure.example.com/". $_SERVER['REQUEST_URI']);

It’s not the most robust, and you can leave out the ” && $_SESSION[‘force_https’]” part as well (it’s basic HTTPS checking for me), but it gets the job done. $_SERVER[‘REQUEST_URI’] is the same as the “$1” above in the Apache (with mod_rewrite) guide.

I know a lot of sites have started to implement this type of feature (forcing HTTPS), such as Facebook, GMail, Hotmail (their HTTPS issue is now resolved), among others. Perhaps though this was a little too late in the game to be starting this. Regardless, I hope these tips have helped you, and you start preparing your users for a more-secured experience!

 Comment on this Post

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: