У меня довольно стандартная настройка с nginx, выходящим из приложения django. Я хочу, чтобы приложение django было только SSL, и поэтому у меня есть два блока прослушивания в моем nginx conf, а трафик, поступающий на порт 80 (HTTP), перенаправляется на порт 443 (SSL). Это работает как ожидалось.
Я запускаю эту настройку внутри виртуальной машины с включенной переадресацией портов, чтобы я мог обозревать сайт с хост-компьютера, перейдя на порт 8080 (HTTP) или 8081 (SSL). Опять же, эта работа прекрасна, как и ожидалось.
Проблема возникает, когда я перенаправляюсь внутри приложения Django во время процесса регистрации. Поскольку Django никогда не видит статус SSL (SSL завершается в nginx, а трафик на приложение перенаправляется на порт 5000 через HTTP), но видит порт, перенаправление становится искаженным **.
Конечным результатом всего этого является то, что я трафик направляется в nginx на порт SSL, а не на SSL, например. http://127.0.0.1:443/
. Есть ли способ настроить nginx для этого?
** NB Я устанавливаю заголовок X-Forwarded-Proto в Nginx, и Django подбирает правильное значение .is_secure(), это особая проблема с внешней библиотекой, не проверяющей is_secure и просто перенаправлением на входящий Схема URL.
[ОБНОВЛЕНИЕ 1]
Прилагаются соответствующие настройки конфигурации. Это из самого Vagrantfile, показывающего перенаправление портов:
config.vm.forward_port 80, 8080 # website, via nginx (redirects to SSL:8081)
config.vm.forward_port 443, 8081 # website, via nginx (accepts SSL)
config.vm.forward_port 5000, 8180 # website, via gunicorn (direct)
Используя приведенную выше конфигурацию перенаправления портов, если я перейду на сайт на главной машине на HTTP-порту (8080), тогда запрос будет принят, а nginx (см. ниже) перенаправляет этот запрос на HTTPS (работает на порту 8081). Когда я нахожусь на HTTPS, сам сайт отлично работает:
(host) http://127.0.0.1:8080 -> forwarded to -> (guest vm) http://127.0.0.1:80
(host) https://127.0.0.1:8081 -> forwarded to -> (guest vm) https://127.0.0.1:443
Проблема возникает, когда я получаю внутреннюю переадресацию из Django, смешанную схему и протокол, и заканчивается запросом на http:\\127.0.0.1:8081\...
, который терпит неудачу, поскольку nginx ожидает, что трафик на 8081 будет SSL.
То, что я действительно хочу, - это правило, в котором говорится: "Слушайте 443 как для SSL, так и для не SSL и перенаправляйте не SSL".
Это соответствующая конфигурация nginx:
# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
server 127.0.0.1:5000 fail_timeout=0;
}
server {
listen 80;
# 8081 is the port I am forwarding to on the host machine
rewrite ^ https://127.0.0.1:8081$request_uri? permanent;
}
server {
listen 443;
ssl on;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!ADH:!MD5;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/nginx/ssl/self-signed.crt;
ssl_certificate_key /etc/nginx/ssl/self-signed.key;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location /static/ {
alias /app/static/;
}
location /media/ {
alias /app/media/;
}
location / {
# everything else is to be served by the django app (upstream 'gunicorn')
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# this is set to ensure that django is_secure returns True
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass http://gunicorn;
}
}