Securing Your Website – SSL a how-to guide

I attended the Optimera STHLM conference this spring where SSL was a recurring theme. The speakers convincingly argued for more extensive use of SSL in websites. Consider that without SSL anyone can see what you read online, what you look at and what your interests are… I was pretty confident after the conference about setting up a website with SSL, and I got the chance to test it out soon after. In the process I discovered that sometimes it’s a bit tough to find information when you have a problem with the implementation, or when you want to learn more. So here’s a how-to guide with what I learned and links to the resources I used most. Maybe it’ll help you, and hopefully you can give me some feedback 🙂

So let’s get started!

NB: My experience is limited to a web application running on an Apache2 web server with a Tomcat6 app server.

Certificates and Keys

The first step to working with SSL is to enable it on your local development machine so you can try it out first. There are lots of resources available for getting certificates, I used OpenSSL to create a self-signed certificate (There’s a great description on how to do that here), for local testing. Take a look at OpenSSl’s documentation for generating a signed certificate that you can use on your public site.

Enabling SSL in Apache

Once you have your certificate and key you can enable SSL in Apache. In a default Apache installation the conf directory includes a directory called extra, there you’ll find the default httpd-ssl.conf file, which you can edit to work with your SSL certificate and key. Find the SSLCertificateFile and SSLCertificateKeyFile properties, either place your certificate and key where they suggest, or edit them to point to your files. Make sure to set the correct DocumentRoot and ServerName, and specify your SSL log locations.

To start using this configuration you add the following line to your httpd.conf file:
Include /[your-apache-path]conf/extra/httpd-ssl.conf

Next, restart apache:
sudo /[your-apache-path]/bin/apachectl -k graceful

If you don’t usually test locally with Apache you can always set up your local machine so that it’s called localtest.companysite.com by adding this entry to your /etc/hosts file:
127.0.0.1 localtest.companysite.com

Now you can use this as your ServerDomain in your httpd and ssl configurations.

Try it out! https://[ServerDomain]. You’re probably getting a certificate warning, this is because you’re using a self signed certificate, and that’s ok (on Firefox this also means that you’re getting a blue bar instead of a green one in your address bar)! On your production server you should use a properly signed certificate so that your users don’t have to deal with this warning.

Fixing Non-Secure Data

Now it’s time to start clicking around on your site. If you’re using Firefox you’ll want to make sure that your address bar is blue the whole time. If it’s not, you probably have non-secure content being requested on your site. In IE this translates to a really annoying pop-up about non-secure items. Make sure that all request are transmitted via https to fix this problem. Possible suspects include external images/flash files, and tracking or analytics JavaScript or iframe source urls. Open up Firebug/HTTPWatch and take a look at your data traffic, change anything that is using http to https.

Proxies and RewriteRules

Some of your http traffic may come from external sites that do not offer https. Luckily this is easy to fix using the same tricks you would use for cross-domain scripts for AJAX. On Apache this means adding a proxy for the non-secure URL. You can do that using ProxyPass, or RewriteRules. The changes here are pretty simple, choose a path that you’ll use to access this external application, so if the original URL is:
http://externalapp.com/somepath/somefile

you could map this to:
https://[serverdomain]/externalapp/somepath/somefile.

The RewriteRule could look like this:

RewriteRule ^/externalapp/(.*)$ http://external.app.com/$1 [P]

The first part is just a regular expression that matches on the path starting with externalapp. The second part is the mapping to the external url, which just tacks on the rest of the path that is needed by the external site. The [P] specifies that this is a ProxyPass. Pretty simple! Now none of your traffic has to go through non-secure connections. If you don’t have access to your Apache installation or aren’t allowed to make this kind of change you can always write your own proxy servlet. Keep in mind that with proxy solutions your external partners’ data will now be served by your servers. If this is a significant increase of your traffic you should consider seeing if your partners can offer their content through https.

Obscure Non-Secure Data

One of the oddest errors I ran into once the site had a nice blue address bar in Firefox, was a page that worked just fine in all browsers except IE 7 and 8! Even though all traffic was going via https I was getting the non-secure data warning. Luckily I found an old article on The Weekly Whinge that explained the problem. It turns out that setting a background image in JavaScript is a problem for IE 7 and 8, even if the image ends up getting requested via https.

Now that you have a blue bar on your local machine it’s time to test this out on a test server with a proper SSL certificate, and make sure you’ve got a green bar everywhere. That’s about it. Except we never did do anything with our Tomcat, should we?

What About the App Server?

The answer depends on your setup. If your application is only available via Apache, traffic between Apache and the app server can continue to go via a non-secure connection, since it’s behind a firewall this should not be a big risk, but only you can determine if this is the right level of security for your application. Assuming that you are ok with communicating via a non-secure connection to the app server then your setup is complete. There is, however, one pitfall that you should watch out for.

Mixing http and https

It’s generally a really bad idea to mix http and https on your site, especially when you are storing session information. In Tomcat a session that is created in response to a non-secure request will by default be non-secure! If you do not explicitly create a new session when the user enters secure areas of your site they will continue using this same non-secure session, which defeats the purpose of using SSL in the first place.

Conversely if the session is first created in response to a secure request it will be a secure session, which sounds great, but is also tricky. When the user navigates to a non-secure area of the site, a new non-secure session will be created invalidating the secure one. This is to protect the user from sending/receiving secure information over a non-secure connection.

If your requirements specify that it’s ok for the session to expire as soon as you leave the secure part of the site, then make sure you handle sessions properly. You should always create a new session as soon as you enter a secure area of your site, make sure you’re not reusing an existing non-secure session and just be aware that the session will expire when you go back to a non-secure area of your site. (If you’re working with JSP’s keep in mind that they will silently create a session by default unless you explicitly prevent them from doing so by adding <%@ page session=”false“>)

If you need to maintain session information across the whole site take a close look at your reasons for mixing http and https… do you have external resources that are served over http? Well you can use a proxy for that. Is it due to performance reasons? The handshake is the most expensive part, so minimize the number of handshakes and you should be doing ok. There’s good information to be found on the mod_ssl page (read the section on cach settings). There’s also a really nice writeup with lots of helpful links and useful comments on this blog post from DynaTrace.

Do your research! Make sure that a green bar really does mean a secure connection, that your session is secure, and that your SSL settings are optimized for your site!

What has your experience with SSL been? Any thoughts about BEAST, and what this means to internet security?

Get in touch via my homepage if you have questions or comments!