KVISH
KVISH

Reputation: 13178

SSL at ELB but setup with Apache

Right now I have a SSL enabled website. The SSL is at the ELB level, so the apache http server never sees it. I'm trying to make it so that Apache will force all requests to have https so there is no http requests being made. I was reading several other posts on SO including this:

Django and SSL question

https://serverfault.com/questions/410542/disable-https-for-certain-path-in-nginx-results-in-instance-behind-elb-going-int

http://www.acmedata.in/2012/08/31/how-to-host-a-django-app-behind-elb-with-ssl/

Can I make use of ELB configuration for this? Or do I have to remove the private key, etc. from the ELB and put it all at the web server level? I was unable to find any further information regarding this...

Upvotes: 2

Views: 879

Answers (2)

David Levesque
David Levesque

Reputation: 22441

You can force https by adding a rewrite rule like this to your Apache configuration:

<VirtualHost *:80>
    ...
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]
    ...
</VirtualHost>

The key here is the X-Forwarded-Proto header. The ELB handles https and forwards requests to Apache as http, and it also adds this header in the process. The rewrite rule checks this header to only redirect http requests that don't originate from the ELB.

Upvotes: 5

Ron E
Ron E

Reputation: 2254

You can handle this at the django level, this is what I use:

from django.http import HttpResponsePermanentRedirect
from django.conf import settings


class SecureRequiredMiddleware(object):
    def __init__(self):
        self.paths = getattr(settings, 'SECURE_REQUIRED_PATHS')
        self.enabled = self.paths and getattr(settings, 'HTTPS_SUPPORT')

    def process_request(self, request):
        if self.enabled and not request.is_secure():
            full_path = request.get_full_path()

            for path in self.paths:
                if full_path.startswith(path):
                    secure_url = request.build_absolute_uri(full_path).replace(
                        'http://', 'https://')
                    return HttpResponsePermanentRedirect(secure_url)

Add that to a file and point to it with your middleware settings. Then you will need to add two settings items. The first is called SECURE_REQUIRED_PATHS and it should be a list of URL's like so:

SECURE_REQUIRED_PATHS = [
    '/login',   #  require HTTPS for any URL starting with `/login`
    '/account', # require HTTPS for any URL starting with `/account`
    '/',        # require HTTPS for all URLs
]

The second should be a flag called HTTPS_SUPPORT:

HTTPS_SUPPORT = True

Then anytime a user access a URL in your SECURE_REQUIRED_PATHS with HTTP, they will be redirected to the HTTPS equivalent.

Upvotes: 2

Related Questions