Apache LinuxApache HTTP Server 2.4

Apache mod_rewrite создаёт бесконечный редирект на HTTPS за Nginx

  • Обновлено
  • Чтение ≈ 4 минуты
  • Нужны права администратора

Краткий ответ

Почему HTTPS-зацикливается при TLS на Nginx и HTTP между Nginx и Apache; безопасное устранение повторяющихся 301/302.

В этой статье
  1. Что означает проблема
  2. Как различить причины
  3. Подробная диагностика и устранение
  4. Как проверить результат
  5. Если проблема не устранена

#Что означает проблема

Снаружи браузер приходит по HTTPS на Nginx, но внутреннее соединение Nginx → Apache может идти по HTTP. Если Apache применяет правило RewriteCond %{HTTPS} !=on и каждый раз отправляет клиента на https://тот-же-адрес, браузер получает бесконечный цикл. Похожий цикл может создавать само PHP-приложение; источник редиректа нужно доказать по журналу и заголовкам.

#Как различить причины

Возможная причинаКак узнатьЧто делать
TLS завершается на NginxApache видит HTTP для каждого запроса и снова требует HTTPS.Последовательные ответы 301/302 с одним и тем же адресом Location.Перенести внешний HTTPS-редирект на Nginx и убрать дублирование.
Приложение не знает внешнюю схемуPHP-фреймворк ориентируется на локальный HTTP и сам выдаёт 301.В Apache нет RewriteRule, но редирект остаётся.Настроить доверие внешней схеме в фреймворке только от известного прокси.
Смешаны правила WWW/не-WWWОдин слой добавляет www, другой удаляет, либо прокси переписывает Host.В Location адреса попеременно меняют имя хоста.Выбрать единый канонический домен в одном месте.

#Подробная диагностика и устранение

  1. Зафиксируйте точную последовательность переходовНа своём компьютере в терминале выполните curl -sS -I -L --max-redirs 5 https://example.com/ (замените домен). Ключ -I запрашивает заголовки, -L следует перенаправлениям, --max-redirs ограничивает их пятью. Если сайт не поддерживает HEAD, повторите проверку GET с -D - -o /dev/null. Запишите только коды и Location. Не помещайте в диагностический URL пароли и токены.
  2. Определите, какой уровень возвращает редиректСопоставьте время запроса в access.log Nginx и Apache. Если Apache отвечает 301 на каждый внутренний HTTP-запрос, причина, вероятно, внутри него или приложения. Если Apache не видит повторных запросов, проверяйте правила Nginx, CDN и DNS. Сам заголовок Server ненадёжен: прокси может заменять его.
  3. Найдите обе версии правил HTTPSНа Nginx через SSH посмотрите действующие return 301, rewrite и proxy_pass в sudo nginx -T. На Apache найдите RewriteCond и RewriteRule в VirtualHost и .htaccess, не забывайте настройки панели. Особенно внимательно сравните %{HTTPS}, X-Forwarded-Proto и редирект https://%{HTTP_HOST}%{REQUEST_URI}. Если HTTPS уже обязателен на внешнем Nginx, внутреннее дублирование часто не нужно.
  4. Не разрешайте доверять заголовку любого пользователяВ Nginx для доверенного внутреннего соединения обычно уместен proxy_set_header X-Forwarded-Proto $scheme;; Apache и приложение должны принимать его только от этого прокси. Если Apache слушает публичный порт, посетитель может передать собственный X-Forwarded-Proto: нельзя строить правила безопасности на слепом доверии такому заголовку. Не заменяйте проверку HTTPS простой ссылкой на произвольный входящий заголовок.
  5. Выберите единый ответственный слойДля схемы HTTPS на Nginx → HTTP на Apache самый простой вариант — направлять HTTP-клиентов на HTTPS средствами внешнего Nginx, а из Apache убрать именно повторяющее это правило. Приложение должно знать внешний защищённый URL через подтверждённую настройку доверенного прокси. Сохраните отдельные правила www и авторизации; не удаляйте все RewriteRule ради одного цикла.
  6. Внесите правку и проверьте её до примененияСделайте резервные копии обоих файлов. Если меняется Apache, выполните sudo apache2ctl configtest; если Nginx, sudo nginx -t. Только после Syntax OK или успешного теста Nginx выполните reload соответствующей службы. Проверьте, что адрес http:// перенаправляется не более одного раза на ожидаемый https:// и что на HTTPS больше нет повтора.
  7. Проверьте безопасность ссылок и входаОткройте страницу входа, пару вложенных маршрутов и форму обратной связи по HTTPS. Убедитесь, что не появляется обратное переключение на HTTP и что cookie с флагом Secure не теряются. Не выключайте HSTS и проверку сертификата для устранения цикла: неправильный переход нужно исправлять в настройках.
  8. Откат и дальнейшая проверкаЕсли после правки исчезла переадресация HTTP → HTTPS или начались ошибки входа, восстановите изменённый файл из копии и перезагрузите проверенную конфигурацию. Затем проверьте настройки base URL и доверенного прокси приложения. Не увеличивайте лимиты перенаправлений клиента: это лишь скрывает неисправность.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Терминал пользователя; замените домен, sudo не нужен.
    Linux · Терминал (Bash)Команда
    Терминал пользователя; замените домен, sudo не нужен. Запрос HEAD может отличаться от GET.
    curl -sS -I -L --max-redirs 5 https://example.com/
    Вариант 2SSH на соответствующих узлах после резервной копии; если тест провален, не выполняйте reload.
    Linux · Терминал (Bash)КомандаНужен sudo
    SSH на соответствующих узлах после резервной копии; если тест провален, не выполняйте reload.
    sudo apache2ctl configtest
    sudo nginx -t
    Вариант 3Показан распространённый источник цикла на внутреннем HTTP после TLS-терминации; НЕ вставлять это правило к…
    Текст
    Показан распространённый источник цикла на внутреннем HTTP после TLS-терминации; НЕ вставлять это правило как решение.
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

#Как проверить результат

Для http://example.com/ цепочка заканчивается корректным HTTPS; для https://example.com/ нет повторяющихся 301/302 на тот же адрес. Проверены Host, авторизация и вложенные страницы.

#Если проблема не устранена

Если цикл остаётся, отключать HTTPS не нужно: отдельно анализируйте, какой слой создал каждую строку Location. Сохраните цепочку заголовков без приватных параметров и логи времени теста.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.