Greetings,
SSL and DNN. Have you ever tried to implement it? If you have, then you're familiar with the pain that is properly implementing SSL in a DNN deployment. For that reason, I've developed this guide to discuss things that I think are important to consider and may help others build better, more secure communities without a lot of headache.
It should be noted that this guide was developed for use in configuring IIS 6.0 on a Windows Enterprise Server 2003 with SP1 installed and worked for both DNN 3.2.2 and DNN 4.0.3. I make no guarantees of success on system configurations different from the one above.
The critical question
When you consider the security of your site's data, ask yourself this question: Which is more important, that data be available over SSL, or that data not be available over non-SSL? Read the question carefully, because it's a critical question. Too many times site administrators look to SSL-implementing solutions that provide a method for enabling SSL, but then do nothing to ensure that access to the data by any other means is totally turned off.
Now I'm not one for calling names, but in particular, there are some third-party SSL modules and code-insertion hacks floating around that claim a large range of functionality from providing SSL redirects via embedded javascript or vbscript in Text/HTML modules loaded onto pages in the DNN site to having entire modules that can control and manipulate SSL access in many different ways. The pitfall of all of these solutions is that in almost every case, work-arounds can be found that allow for access to the raw data without passing over the triggers and events that are intended to protect the user from an unsecured channel.
Turning on true SSL protection
So if triggers and events aren't such a good idea, what can we do? Well, there is an option in IIS 6.0 that allows an entire site to be accessible via SSL and only accessible via SSL. It's a great little option.
Simply follow these steps to turn on true SSL protection.
- Right-click on your website in the IIS 6.0 Manager.
- Select "Properties."
- Tab to "Directory Security."
- Locate the "Secure communications" grouping and click on the "Edit" button. Note: this will only be available if you have installed a SSL certificate for this site.
- Check the option "Require secure channel" on the next pop-up window.
- Check "Require 128-bit encryption."
- Click "Okay" twice to return to the IIS 6.0 Manager.
- Restart the IIS 6.0 service for good measure if running user-mode SSL. If you are running kernel-mode SSL it is a requirement. Note: this is not the same as stoppingg and restarting your individual site. See below for more information.**
Give yourself a pat on the back, your site is now entirely SSL accessible and restricted without the mess of a code hack or third-party module.
You can also test the implementation. Try accessing any part of your site using the non-SSL method and you'll be greated with a nice 403.4 error. Neat huh? Best part is, we're going to take this error and use it to our advantage to add even more functionality to our site. Read on!
** In some applications, moving SSL processes and references from user-mode to kernel-mode can have serious benefits in terms of resources. There's a full write-up here on Microsoft's web site. I leave the implementation of this option to the user as it may or may not work for your unique set of needs. It is good to know about though.
Dealing with the 403.4 error
So now we're setup so any request to https://www.soandso.com takes us to our site, but this is going to be annoying. How many of us actually go to websites typing in https instead of http? Not a single one I bet. Wouldn't it be nice if the error display was actually our site?
It ends up that we can use the 403.4 error to remap the user from the nasty display of the 403.4 error details to our https://www.soandso.com address! This is a long procedure, so try to follow each step carefully:
Step 1: Reconfigure the default file served.
- Right-click on your website in the IIS 6.0 Manager.
- Select "Properties."
- Tab to "Documents."
- Write down somewhere the list of files named in the "Default Content Page" group. You'll need these later.
- Remove the existing file names from the "Default Content Page" group, and then add a file name not yet in use on your site. Note: for my implementation I used Redirect.aspx since that is what this file will be doing: redirecting.
- Click "Okay" to return to IIS 6.0 Manager.
At this point, if you try to browse your site using https, you're going to get a new error. This is because you've specified the use of a default file that doesn't exist. If you try to browse using http, you'll still get the 403.4 error. Check this to make sure you're on the right track.
Step 2: Create redirecting file and configure SSL to allow non-SSL transmission of redirecting file.
- Browse to your site's file directory using a file browser, and create an empty file matching the name that you specified in step1. For now, leave it empty.
- Go back to IIS 6.0 Manager, and refresh your view of the root directory. The new file should now be listed.
- Right click on this file.
- Select "Properties."
- Tab to "File Security."
- Locate the "Secure communications" grouping and click on the "Edit" button. Note: this will only be available if you have installed a SSL certificate for this site.
- Uncheck the option "Require 128-bit encryption" on the next pop-up window.
- Uncheck "Require secure channel."
- Click "Okay" twice to return to the IIS 6.0 Manager.
At this point, if you try to browse your site using https, you're going to get a blank page. This is because the default file now exists but nothing is in it. If you try to browse using http, you'll still get the 403.4 error. Check this to make sure you're on the right track.
You might be wondering why we're making this new file and setting it to non-SSL as opposed to just setting Default.aspx to non-SSL and putting our redirecting code in it.
Well, it's a good question and here's the problem. If you turn on "Require secure channel" at the site level, whatever default files you have listed will ALWAYS be served using SSL if they're accessed using the default mechanism. Even if you turn off SSL for the default file itself and leave it on at the site level, behavior is messed up. You'll observe that http://www.soandso.com/Default.aspx is browseable, but http://www.soandso.com is not because the later address is bound to the site's settings, not the file's.
This is where most people struggle in implementing SSL. You'll also find that if you turn off SSL at the site level, turn it on for everything under the site manually (which is a big pain), and then turn it off for Default.aspx, weird stuff starts to happen because the preprocessor inserts what should be protected information into an unprotected file and then serves that over non-SSL, constituting a breach.
Step 3: Replacing 403.4's error file with the redirect file.
- Right-click on your website in the IIS 6.0 Manager.
- Select "Properties."
- Tab to "Custom Errors."
- Find the 403;4 entry, highlight it, and click on "Edit".
- Change Message Type to "URL"
- Change URL to the relative path of your redirect file. Note: in my case, the value was changed to "/Redirect.aspx" without the quotes.
- Click "Okay" twice to return to the IIS 6.0 Manager.
At this point, if you try to browse your site using https, you're going to get a blank page. We saw this before, so no big deal. If you try to browse using http, you'll now get a blank page instead of the error page. This is because the default page accessed via https is the same as the error file used when we browse using http. Check this to make sure you're on the right track.
Step 4: Scripting the redirect file.
Browse to your site's file directory using a file browser, and open the empty file matching the name that you specified in step1 with your favorite editor.
Inside of this file, place code that looks something like this:
<%
Dim strSecureURL, srvHTTP_HOST, srvSERVER_PORT_SECURE, srvQUERY_STRING As String
srvHTTP_HOST = Request.ServerVariables("HTTP_HOST")
srvSERVER_PORT_SECURE = Request.ServerVariables("SERVER_PORT_SECURE")
srvQUERY_STRING = Request.ServerVariables("QUERY_STRING")
If (srvSERVER_PORT_SECURE = "0") Then
strSecureURL = srvQUERY_STRING.Replace("403;http://www.soandso.com:80", https://www.soandso.com)
Else If (srvSERVER_PORT_SECURE = "1") Then
strSecureURL = "https://www.soandso.com/Default.aspx"
End If
Response.Redirect(strSecureURL)
%>
This is probably where people will deviate the most since there's many ways to code this. There are some things to be careful about, so I'll explain the important parts.
First, I've used the SERVER_PORT_SECURE={0|1} approach to detect if the pipe is secure rather than SERVER_PORT={xxx|yyy} because not everyone runs their webservers on the default ports. This is a more generic approach.
Second, both secure and non-secure require redirection, without the use of the URL server variable (not used in the above code). The reason for this is because in all cases, the actual URL path being referenced by both https (default mechanism) and http (error mechanism) is /Redirect.aspx, so its of no use.
Third, I've included the HTTP_HOST reference for folks who may be using host headers. You'll need to conditionally look at this variable to find out how to make additional changes to the strSecureURL variale so that host headers get mapped correctly.
Fourth, notice the explicit use of Default.aspx in the URL for when a user is using a secure channel. Without this included in the URL, the site will loop, redirecting to the redirecting to the redirecting and so on.
Conclusion
Now you should be set. Give it a whirl and see how things turn out. This solution also works with or without Friendly URL's which I thought was a huge bonus. To see if the SSL condition breaks, burrow down into your site in a web browser and then see if replacing the https with http makes a difference. In each case you should be forwarded to the https side of life, or possibly to a 404 eror if you try to find something that doesn't exist.
If you find a flaw in this solution, let me know. I'm interested in the communities feedback.
Thanks,
Casey
Research in Computing for Humanties - Network Administrator
The STOA Consortium - Web Administrator
University of Kentucky