SSL Security (HTTPS) in Django one-click-install configuration

March 4, 2015 6.2k views
Django Nginx Configuration Management Ubuntu

Hello All,
I am quite new to server administration, especially on Linux, but if I understand correctly the Droplet I created with DO's Django one-click-install is set up so the only Nginx is exposed, and it both servers static files and works as a Proxy for Guincorn, which handles all Django pages.

According to Django Doc (https://docs.djangoproject.com/en/1.7/ref/settings/#secure-proxy-ssl-header), when Django is served behind a proxy, I need to set the SECUREPROXYSSL_HEADER (in my settings.py).

Also Django Doc has this BIG WARNING where it says I have to make sure that:

  • - Your proxy strips the X-Forwarded-Proto header from all incoming requests. In other words, if end users include that header in their requests, the proxy will discard it.
    • Your proxy sets the X-Forwarded-Proto header and sends it to Django, but only for requests that originally come in via HTTPS.*

How do I do that? And how do I do that "properly", avoiding any security holes?

Following is my Nginx settings file (Based on DO's guides I found).
I do not understand completely the "location" block, toward the end... is it properly configured for secure HTTPS? (proxy_redirect is off, and proxy_pass set to non-secure address http://app_server, which I do not understand, does it have to do with Guinicorn?)

Thanks for any help might provide :)


  upstream app_server {
    server 127.0.0.1:9000 fail_timeout=0;
  }

  # redirect all requests to SSL
  server {
    # v. http://serverfault.com/questions/67316/in-nginx-how-can-i-rewrite-all-http-  requests-to-https-while-maintaining-sub-dom

    listen 80;
    listen [::]:80 ipv6only=on;

    return 301 https://$host$request_uri;
  }

  # SSL
  server {
    listen 443 default_server;
    listen [::]:443 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    client_max_body_size 4G;
    server_name www.brainbk.com;

    keepalive_timeout 5;

    # Use HTTP Strict Transport Security (HSTS)
    #  v. Django Doc: https://docs.djangoproject.com/en/1.7/topics/security/
    #  v. https://gist.github.com/plentz/6737338
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

    # Your Django project's media files - amend as required
    location /media  {
        alias /home/django/MyMemoProject/MyMemoProject/media;
    }

    # your Django project's static files - amend as required
    location /static {
        alias /home/django/MyMemoProject/static;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server;
    }

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
  }
1 comment
  • I just found someone who had the same problem a couple of years ago. If this (http://serverfault.com/questions/386755/nginx-strip-header-on-http-add-header-on-https) is still valid, my solution would simply be to add to the "location" block of my config file this line:

    proxy_set_header X-Forwarded-Proto $scheme;
    
    

    Is this correct? Also, even if adding the ling is enough, any better clarification/explanation is more than welcome. As I still do not understand how everything comes together, and leaving security holes is quite easy, being ignorant ;)

    Thanks again!

1 Answer

This question was answered by @cattiveria:

I just found someone who had the same problem a couple of years ago. If this (http://serverfault.com/questions/386755/nginx-strip-header-on-http-add-header-on-https) is still valid, my solution would simply be to add to the "location" block of my config file this line:

proxy_set_header X-Forwarded-Proto $scheme;

Is this correct? Also, even if adding the ling is enough, any better clarification/explanation is more than welcome. As I still do not understand how everything comes together, and leaving security holes is quite easy, being ignorant ;)

Thanks again!

View the original comment

Have another answer? Share your knowledge.