简体   繁体   中英

HTTP to HTTPS with health link on Elastic Beanstalk using Django

I am trying to redirect Http to Https in Django deployed on AWS Beanstalk. Http to Https works fine when I remove the health link from the load balancer. while having link in load balancer the app stops working.

I am using the following config in settings file in the Django project hosted on Aws Beanstalk.

CORS_REPLACE_HTTPS_REFERER = True
HOST_SCHEME = "https://"
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

With SECURE_SSL_REDIRECT = True all non-secure requests will be redirected to https. Non-secure requests - ones done via http and with not matched SECURE_PROXY_SSL_HEADER .

Even if your load balancer performs http to https redirect by itself - it is good to have this option enabled in django and simplier (all security options enabled).


AWS ALB Health Checks cannot set custom headers. We can exclude requests to certain endpoints from being redirected to https with SECURE_REDIRECT_EXEMPT - [r'^health/$'] .


AWS ALB Health Check requests are done to instance ip. To allow django process them - ip needs to be added to ALLOWED_HOSTS : ["172.16.2.5", "my.example.com"] . This needs to be instance private ip, one that will be used by ALB to reach it.

This can be done with:

  • Adding instance ip on instance start like in example . It can also be done with custom scripts and environment variables.

  • using custom middleware which allows adding ip ranges in ALLOWED_HOSTS and add VPC Subnet range or implement custom middleware manually


AWS ALB cannot add HSTS headers. If you want to use Strict Transport Security headers - they should be added on app django side. This can be done with setting SECURE_HSTS_SECONDS other than zero.

HSTS headers are only added on responses to secure requests ( https:// or SECURE_PROXY_SSL_HEADER match).

I had the same problem and I fixed it with a middleware (python 3.x):

production settings.py:

MIDDLEWARE = ['market.middleware.ELBHealthChecker_middleware'] + MIDDLEWARE

ELB middleware:

def ELBHealthChecker_middleware(get_response):

    def middleware(request):
        response = get_response(request)
        if "ELB-HealthChecker" in request.META["HTTP_USER_AGENT"]:
            from django.http import HttpResponse
            return HttpResponse(status=200)
        return response
    return middleware
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True

These have worked for me in the past.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM