I
I
Ilya Sayakhov2015-12-22 19:00:29
Django
Ilya Sayakhov, 2015-12-22 19:00:29

nginx + gunicorn + ssl Different configs for different subdomains on the same certificate. Is it possible?

Hello! Need help. Killed a day to configure nginx so that it gives different sites to django from one ssl certificate (the certificate supports several subdomains).

Config for the main domain

upstream example.com {
        server unix:/path/to/env/run/gunicorn.sock fail_timeout=0;
}

server {
        listen 443 ssl;
        server_name example.com;

        client_max_body_size 4G;

        ssl on;
        ssl_certificate /path/to/ssl/example.com.crt;
        ssl_certificate_key /path/to/ssl/example.com.key;

        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        ssl_prefer_server_ciphers on;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate "/path/to/ssl/ca-certs.pem";
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'HIGH:!aNULL:!MD5:!kEDH';
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 5s;

        access_log /var/logs/nginx-access.log;

        error_log /var/logs/nginx-error.log;
 
        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_set_header Host $http_host;
                proxy_redirect off;

                if (!-f $request_filename) {
                        proxy_pass http://example.com;
                        break;
                }
        }
}


Config for subdomain

upstream sub.example.com {
        server unix:/path/to/sub/env/run/gunicorn.sock fail_timeout=0;
}

server {
        listen 443 ssl;
        server_name sub.example.com;

        client_max_body_size 4G;

        ssl on;
        ssl_certificate /path/to/ssl/example.com.crt;
        ssl_certificate_key /path/to/ssl/example.com.key;

        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        ssl_prefer_server_ciphers on;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate "/path/to/ssl/ca-certs.pem";
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'HIGH:!aNULL:!MD5:!kEDH';
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 5s;

        access_log /var/logs/nginx-access.log;

        error_log /var/logs/nginx-error.log;
 
        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_set_header Host $http_host;
                proxy_redirect off;

                if (!-f $request_filename) {
                        proxy_pass http://sub.example.com;
                        break;
                }
        }
}


At the moment, the main domain is working, but the subdomain either issues an endless redirect or loads the main site.
Please help!
UPDATE: Found a problem. It turned out that it was not the case with nginx at all. I experimented with the django settings and added the SECURE_SSL_REDIRECT = True option, which created all this nonsense. Crap..

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
Ilya Sayakhov, 2015-12-22
@newca9h

Found a problem. It turned out that it was not the case with nginx at all. I experimented with the django settings and added the SECURE_SSL_REDIRECT = True option, which created all this nonsense. Crap..

Y
Yuri, 2015-12-22
@xtreme

upstream subexample.com {
and
Here it is not clear why describe upstream and not use it. Or is it a typo?
Secondly, the purpose of the design is not clear:

if (!-f $request_filename) {
  proxy_pass http://sub.example.com;
  break;
}

I read this - if the file does not exist, then make a proxy_pass to itself and get an endless redirect (this is in case there is no typo and proxies to sub.example.com), or use the http protocol to access the backend that hangs on the socket and then we get garbage, because the resulting url is rather unusual http://unix://....
The question immediately arises... what if the file is found? Where to give it? There are no other options visible.
I would recommend:
- don't name upstreams the same as real servers - one mistake and you get unpredictable behavior that is very hard to catch. Ideally, upstreams can be named in one word, so as not to be confused with the name of the server.
- Try to do without if in the config, especially for checking the existence of a file. There are also try_files.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question