Назад | Перейти на главную страницу

Запретить nginx перенаправлять трафик с https на http при использовании в качестве обратного прокси

Вот моя сокращенная версия nginx vhost conf:

upstream gunicorn {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com ~^.+\.domain\.com$;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 120;
        proxy_pass http://gunicorn;
    }
}

Один и тот же сервер должен обслуживать как HTTP, так и HTTPS, однако, когда восходящий поток выдает перенаправление (например, после обработки формы), все запросы HTTPS перенаправляются на HTTP. Единственное, что я нашел, что исправит эту проблему, - это изменение proxy_redirect на следующее:

proxy_redirect http:// https://;

Это прекрасно работает для запросов, поступающих с HTTPS, но если перенаправление выполняется по HTTP, оно также перенаправляет его на HTTPS, что является проблемой.

От отчаяния я попробовал:

if ($scheme = 'https') {
    proxy_redirect http:// https://;
}

Но nginx жалуется, что proxy_redirect здесь нельзя.

Единственный другой вариант, который я могу придумать, - это определить два сервера отдельно и установить proxy_redirect только на SSL, но тогда я бы продублировал остальную часть conf (в server директиву, которую я опустил для простоты). Я знаю, что могу также использовать include директиву, чтобы исключить избыточность, но я действительно хочу сохранить только один файл conf без каких-либо зависимостей.

Итак, во-первых, есть ли что-то, что мне не хватает, что полностью устранит проблему? Или, во-вторых, если нет, есть ли другой способ (помимо включения внешнего файла) исключить избыточную информацию о конфигурации, чтобы я мог разделить версии HTTP и HTTPS конфигурации сервера?

Что ж, немного вдохновения я попробовал:

proxy_redirect http:// $scheme://;

Что, кажется, помогает. Однако мне это все еще кажется хакерским, поэтому я по-прежнему приветствую любые советы по поводу того, что я делаю неправильно, или менее хакерские способы достижения того же результата.

Другое решение - указать восходящему потоку, является ли запрос HTTP или HTTPS, и выполнить соответствующее перенаправление. Добавление этого в конфигурацию nginx установит заголовок для проверки восходящим потоком.

proxy_set_header    X-Scheme $scheme;