monitoring Security Technology

Route53 healthcheck failover for SSL pages with nginx

UPDATE: AWS recently introduced SSL Health checks. So the method in this post should no longer be necessary.

Amazon Route53 offers a DNS healthcheck that allows you to failover to another host / region if one IP is not responsive. This works great if you want to create a secondary site, or even a simple maintenance page to give your users a little more info than just an empty browser window.

There are some limitations to the healthchecks currently. Route53 allows you to choose between TCP and HTTP. However, there’s no HTTPS / SSL support for URLs.

So what can you do if your site is running only with SSL?

You can check that the HTTP connection to the server works. On many sites, this would produce a redirect to the HTTPS version of the page. Unfortunately, this will be considered as down by Route53.

You can open up your site over HTTP, but that would compromise the security of your users.

A third option is to create a special page of the app (something like /status), which would be available over HTTP. This however requires changing your application (as well as opening up HTTP for this page).

I suggest a reasonable compromise that seems to work well. It’s some kind of a variation on the third option. The solution does involve opening the site over HTTP.

However, there’s a little twist. The site will only be avaialble over HTTP if (and only if) a specific hostname is provided. This particular hostname does not (and should not) be defined on your DNS. It’s hidden. Only the AWS health-check will use it!

For those who would (rightfully) say, this is security through obscurity: You’re (kinda) right. However, normal users won’t need to use this link. Attackers can’t easily use it either (unless they can change the local hosts file on the target machine, in which case all bets are off anyway). So it’s a reasonable compromise in my opinion. This hostname can be chosen at random and be as complex and difficult to guess as you want.

I’ll demonstrate it using Nginx, but the same can be applied using Apache or any other web server. Here’s the nginx configuration snippet, with annotations:

    server {
        # This is the special hostname we choose.
        # It can be as simple or as complex as you want.
        # It also doesn't even need to be on your domain. ANY name works.
        # The important thing is to use the same name on the `Host Name`
        # field on the Route53 HealthCheck screen

        # listening on port 80
        listen 80;

        # the next section is from a 'standard' unicorn (rails) app
        # use your own app here
        root /var/local/app_name/public;
        try_files $uri/index.html $uri.html $uri @app_name;
        location @app_name {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header CLIENT_IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://unicorn-app_name;

Remember: do not create a DNS record. To test that this URL works, simply update your local /etc/hosts file.

Leave a Reply

Your email address will not be published. Required fields are marked *