@sazhyk

Как правильно настроить HTTPS для связки Nginx и Django?

Настраиваю сервер для продакшена. Необходимо настроить сайт на работу только с HTTPS. В конфиге nginx'а присутствует директива
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^ https://$server_name$request_uri? permanent;
В settings.py
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True

Получаю ошибку
Сайт example.org выполнил переадресацию слишком много раз.
Удалите файлы cookie..
ERR_TOO_MANY_REDIRECTS

в браузере.
Я как бы понимаю что джанга не знает о том, по какому протоколу пользователь обратился. Об этом знает только nginx. Он (nginx) обращается к бэкенду по HTTP. А джанга видит, что к ней пришли по HTTP и редиректит на HTTPS. Я так понимаю, что вот эти две директивы
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
призваны исправить сложившуюся ситуацию.
Так вот вопрос, где я тут косячу и как это исправить?
ЗЫ. настраиваю "по гуглу" и в первый раз. Если нужны для ясности ситуации другие куски кода и конфигов - выложу.
  • Вопрос задан
  • 3851 просмотр
Пригласить эксперта
Ответы на вопрос 1
Скорее всего у тебя запросы попадают в цикличную переадресацию. Если бы выложил весь конфиг nginx, стало бы понятнее.

У меня работает связка Django -> Gunicorn -> Nginx

Nginx прослушивает 80 и 443 внешние порты. При обращении на 80, он переадресовывает на 443.
Django через Gunicorn прослушивает кастомный порт, где принимает HTTP запросы. В настройках Djang'и специальных опций для SSL не добавлял.

Мой nginx конфиг для django.
server {
        listen 80;
        server_name <site_name>;
        return 301 https://<site_name>$request_uri;

}

server {
    server_name <site_name>;
    listen <site_name>:443 ssl;

    gzip on;
    gzip_disable "msie6";
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    ssl_certificate /<path_to_ssl>/fullchain.pem;
    ssl_certificate_key /<path_to_ssl>/privkey.pem;
    ssl_trusted_certificate /<path_to_ssl>/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 127.0.0.1 8.8.8.8;

    add_header Strict-Transport-Security "max-age=31536000";
    add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests";
    expires max;

    location /static/ {
        alias /<project_path>/static/;
        expires 30d;
    }

    location /media/ {
        alias /<project_path>/media/;
        expires 30d;
    }

   location / {
                 client_max_body_size 0;
                 proxy_pass http://<local_ip>:<port>/;
                 proxy_set_header X-Real-IP $remote_addr;
                 proxy_set_header REMOTE_ADDR $remote_addr;
                 proxy_set_header Host $host;
                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                 expires 1h;
        }

}

server {
    server_name www.<site_name>;
    listen www.<site_name>443 ssl;
    access_log off;

    ssl_certificate /<path_to_ssl>/fullchain.pem;
    ssl_certificate_key /<path_to_ssl>/privkey.pem;
    ssl_trusted_certificate /<path_to_ssl>/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 127.0.0.1 8.8.8.8;

    add_header Strict-Transport-Security "max-age=31536000";
    expires max;
    return 301 https://<site_name>$request_uri;

}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы