#Что означает и когда возникает ошибка
Отдельно проверьте, где именно возникает перенаправление: у внешнего прокси, у внутреннего Nginx или в приложении. Не доверяйте X-Forwarded-Proto, присланному любым клиентом из интернета.
#Причины и как их различить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
Nginx формирует редирект по локальной схемеВнутреннее соединение от внешнего прокси идёт по HTTP и $scheme равно http. | Location содержит http://, а входной адрес у пользователя https://. | Перенести публичный редирект на внешний уровень или использовать контролируемую схему. |
| Приложение получает неверный X-Forwarded-ProtoНе передан исходный HTTPS или приложение не настроено доверять собственному прокси. | В приложении генерируются ссылки на HTTP даже при правильном Nginx. | Настроить передачу заголовка на доверенной границе. |
| Разные правила на двух узлахОдин прокси меняет HTTP на HTTPS, другой снова на HTTP. | Цепочка curl показывает повторные Location в разные стороны. | Убрать конфликтующие редиректы, сохранив TLS. |
#Пошаговая диагностика и исправление
- Покажите цепочку ответа без браузераНа своём компьютере откройте терминал (Windows: PowerShell; Linux/macOS: «Терминал») и выполните
curl -I --max-redirs 0 https://example.com/, заменив example.com на домен. НайдитеHTTP/...иLocation:. Команда HEAD может отличаться от GET; при сомнении проверьте GET сcurl -sS -o /dev/null -D - https://example.com/. Не добавляйте в команду пароли и токены. Если Location на HTTP — запишите точный путь и время. - Определите, какой узел отвечает редиректомПо SSH откройте журналы и конфигурацию внешнего прокси и внутреннего Nginx. В
sudo nginx -Tпроверьтеreturn,rewrite,proxy_pass,proxy_set_header,server_name. Для контроля делайте запросы только к принадлежащему вам внутреннему адресу из доверенной сети, явно передавая Host. Не отправляйте внутренний адрес пользователям и не создавайте публичный доступ к административным портам. - Проверьте границу доверия для HTTPSЕсли TLS завершает внешний прокси, он должен устанавливать значение
X-Forwarded-Protoисходя из реального входящего HTTPS, перезаписывая входящее значение, а не бесконтрольно передавая клиентское. Внутренний узел должен принимать такие сведения только от доверенного IP/сети. В типичной конфигурации Nginx, которая сама принимает HTTPS и проксирует приложение, уместноproxy_set_header X-Forwarded-Proto $scheme;; за другим TLS-терминатором$schemeможет быть http, поэтому такая строка не универсальна. - Исправьте правило на конкретном узлеУстановите, кто отвечает за канонический HTTPS-адрес: обычно внешний публичный прокси. Удалите конфликтующий автоматический редирект на HTTP из внутреннего Nginx/приложения. Если приложение поддерживает список доверенных прокси и внешний URL, настройте их по документации именно этого приложения. Не делайте глобальный редирект по неподтверждённому
$http_x_forwarded_proto: это открывает путь к подделке схемы. - Сделайте копию, проверьте и применитеПеред редактированием скопируйте действующий файл конфигурации в отдельный файл с датой и запишите, что меняли. Запустите
sudo nginx -t; при успехе —sudo systemctl reload nginx. Если тест неуспешен, не перезагружайте службу, исправьте ошибку по указанной строке. Если после изменения возник цикл, восстановите копию и снова проведите тест. - Проверьте редиректы и содержимое страницыПовторите curl для
http://иhttps://домена. Ожидается либо прямой ответ по HTTPS, либо короткий переход HTTP → HTTPS без обратного перехода. Откройте страницу в приватном окне и проверьте отсутствие смешанного содержимого по вкладке «Консоль» браузера. Если HTTP-ссылки остались только в HTML, их может генерировать приложение, не Nginx. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Проверка результата
Успех: переходы ведут на один канонический HTTPS-адрес, заголовок Location не уводит на HTTP, и приложение создаёт HTTPS-ссылки.
#Если проблема осталась
Сохраните дату, точный URL без паролей и токенов, код ответа, обезличенные строки error.log и access.log за это время и перечень уже сделанных изменений. Сравните работу при обращении через публичный адрес и через внутренний балансировщик, если он есть. Если причину пока не удалось подтвердить, восстановите исходную конфигурацию из копии и передайте эти сведения администратору или разработчику приложения; не меняйте несколько параметров одновременно.