Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save davewongillies/6897161 to your computer and use it in GitHub Desktop.
Save davewongillies/6897161 to your computer and use it in GitHub Desktop.

Revisions

  1. davewongillies revised this gist Oct 9, 2013. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions Serving Django apps behind SSL with Nginx.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,3 @@
    Serving Django apps behind SSL with Nginx
    ====================
    Configuring Nginx to serve SSL content is straight forward, once you have your certificate and key ready:
    ```
    server {
  2. davewongillies renamed this gist Oct 9, 2013. 1 changed file with 0 additions and 0 deletions.
  3. davewongillies renamed this gist Oct 9, 2013. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions gistfile1.md → Serving Django apps behind SSL with Nginx
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    Serving Django apps behind SSL with Nginx
    ====================
    Configuring Nginx to serve SSL content is straight forward, once you have your certificate and key ready:
    ```
    server {
  4. davewongillies revised this gist Oct 9, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ But you will find, as I did, that Django makes redirections from https to http U

    When Django does a redirection, it composes an absolute URI based on the one in the request object. And the request object uses its method `build_absolute_uri()` to make this URI, which in turn calls another `HttpRequest` method, `is_secure()`, to check whether to use http or https.

    OK, that was all an intro. The interesting bit I want to share is that this is_secure() method works differently under Django 1.3 or 1.4. Under 1.3 it only checks whether an environment variable named "https" exists and its value is "on":
    OK, that was all an intro. The interesting bit I want to share is that this `is_secure()` method works differently under Django 1.3 or 1.4. Under 1.3 it only checks whether an environment variable named "https" exists and its value is "on":
    ```
    def is_secure(self):
    return os.environ.get("HTTPS") == "on"
  5. davewongillies revised this gist Oct 9, 2013. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -24,9 +24,9 @@ server {
    }
    ```

    But you will find, as I did, that Django makes redirections from https to http URLs when you use an HttpResponseRedirect object.
    But you will find, as I did, that Django makes redirections from https to http URLs when you use an `HttpResponseRedirect` object.

    When Django does a redirection, it composes an absolute URI based on the one in the request object. And the request object uses its method build_absolute_uri() to make this URI, which in turn calls another HttpRequest method, is_secure(), to check whether to use http or https.
    When Django does a redirection, it composes an absolute URI based on the one in the request object. And the request object uses its method `build_absolute_uri()` to make this URI, which in turn calls another `HttpRequest` method, `is_secure()`, to check whether to use http or https.

    OK, that was all an intro. The interesting bit I want to share is that this is_secure() method works differently under Django 1.3 or 1.4. Under 1.3 it only checks whether an environment variable named "https" exists and its value is "on":
    ```
    @@ -35,7 +35,7 @@ def is_secure(self):
    ```
    So if you want to make sure you serve secure URLs all the way, you need to setup that environment var.

    But under 1.4 it does another check before doing that one. It looks for the HTTP header X-Forwarded-Protocol, and if it is present, it returns True (https request). This header has to be added to in the Ningx configuration for the secure server so it is passed to gunicorn:
    But under 1.4 it does another check before doing that one. It looks for the HTTP header `X-Forwarded-Proto`, and if it is present, it returns True (https request). This header has to be added to in the Nginx configuration for the secure server so it is passed to gunicorn:
    ```
    location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  6. davewongillies revised this gist Oct 9, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@ location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-Proto $scheme
           proxy_pass  http://unix:/sourcepath/run/app.sock;
       }
    ```
  7. davewongillies revised this gist Oct 9, 2013. 1 changed file with 5 additions and 2 deletions.
    7 changes: 5 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,10 @@ location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
    proxy_set_header X-Forwarded-Protocol https;
    proxy_set_header X-Forwarded-Proto https;
           proxy_pass  http://unix:/sourcepath/run/app.sock;
       }
    ```
    ```
    NB X-Forwarded-Proto
    ===
    I've wasted hours of my life trying to figure out why `X-Forwarded-Protocol` didn't work. Well its because at some point in time, either it worked or the collective consciousness of the Internet got it wrong and perpetuated this incorrect information. The correct `proxy_set_header` is in fact `X-Forwarded-Proto`. Hopefully this tidbit will save you from wasting hours of your life like I did.
  8. davewongillies revised this gist Oct 9, 2013. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -36,7 +36,8 @@ def is_secure(self):
    So if you want to make sure you serve secure URLs all the way, you need to setup that environment var.

    But under 1.4 it does another check before doing that one. It looks for the HTTP header X-Forwarded-Protocol, and if it is present, it returns True (https request). This header has to be added to in the Ningx configuration for the secure server so it is passed to gunicorn:
    ```location / {
    ```
    location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
  9. davewongillies revised this gist Oct 9, 2013. 1 changed file with 5 additions and 4 deletions.
    9 changes: 5 additions & 4 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -29,17 +29,18 @@ But you will find, as I did, that Django makes redirections from https to http U
    When Django does a redirection, it composes an absolute URI based on the one in the request object. And the request object uses its method build_absolute_uri() to make this URI, which in turn calls another HttpRequest method, is_secure(), to check whether to use http or https.

    OK, that was all an intro. The interesting bit I want to share is that this is_secure() method works differently under Django 1.3 or 1.4. Under 1.3 it only checks whether an environment variable named "https" exists and its value is "on":

    ```
    def is_secure(self):
    return os.environ.get("HTTPS") == "on"

    ```
    So if you want to make sure you serve secure URLs all the way, you need to setup that environment var.

    But under 1.4 it does another check before doing that one. It looks for the HTTP header X-Forwarded-Protocol, and if it is present, it returns True (https request). This header has to be added to in the Ningx configuration for the secure server so it is passed to gunicorn:
    location / {
    ```location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
    proxy_set_header X-Forwarded-Protocol https;
           proxy_pass  http://unix:/sourcepath/run/app.sock;
       }
       }
    ```
  10. davewongillies revised this gist Oct 9, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Configuring Nginx to serve SSL content is straight forward, once you have your certificate and key ready:
    <code>
    ```
    server {
       listen 443 default ssl;
       root /path/to/source;
    @@ -22,7 +22,7 @@ server {
       }
    }
    </code>
    ```

    But you will find, as I did, that Django makes redirections from https to http URLs when you use an HttpResponseRedirect object.

  11. AJ revised this gist Aug 3, 2012. 1 changed file with 18 additions and 2 deletions.
    20 changes: 18 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -24,6 +24,22 @@ server {
    }
    </code>

    But you will find, as I did, that Django makes redirections from secured to unsecured URLs when it calls an HttpResponseRedirect object.
    But you will find, as I did, that Django makes redirections from https to http URLs when you use an HttpResponseRedirect object.

    This happens because the HttpResponseRedirect code uses
    When Django does a redirection, it composes an absolute URI based on the one in the request object. And the request object uses its method build_absolute_uri() to make this URI, which in turn calls another HttpRequest method, is_secure(), to check whether to use http or https.

    OK, that was all an intro. The interesting bit I want to share is that this is_secure() method works differently under Django 1.3 or 1.4. Under 1.3 it only checks whether an environment variable named "https" exists and its value is "on":

    def is_secure(self):
    return os.environ.get("HTTPS") == "on"

    So if you want to make sure you serve secure URLs all the way, you need to setup that environment var.

    But under 1.4 it does another check before doing that one. It looks for the HTTP header X-Forwarded-Protocol, and if it is present, it returns True (https request). This header has to be added to in the Ningx configuration for the secure server so it is passed to gunicorn:
    location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
    proxy_set_header X-Forwarded-Protocol https;
           proxy_pass  http://unix:/sourcepath/run/app.sock;
       }
  12. AJ revised this gist Aug 1, 2012. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Configuring Nginx to server SSL content is straight forward, once you have your certificate and key ready:
    Configuring Nginx to serve SSL content is straight forward, once you have your certificate and key ready:
    <code>
    server {
       listen 443 default ssl;
    @@ -22,4 +22,8 @@ server {
       }

    }
    </code>
    </code>

    But you will find, as I did, that Django makes redirections from secured to unsecured URLs when it calls an HttpResponseRedirect object.

    This happens because the HttpResponseRedirect code uses
  13. AJ created this gist Aug 1, 2012.
    25 changes: 25 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    Configuring Nginx to server SSL content is straight forward, once you have your certificate and key ready:
    <code>
    server {
       listen 443 default ssl;
       root /path/to/source;
       server_name mydomain;

       ssl_certificate      /path/to/cert;
       ssl_certificate_key  /path/to/key;


       client_max_body_size 10M;
       access_log /var/log/nginx/alog.log;
       error_log /var/log/nginx/elog.log;


       location / {
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
           proxy_pass  http://unix:/sourcepath/run/app.sock;
       }

    }
    </code>