Apache (http) за балансировщиком нагрузки (http/https) – перенаправление не сохраняет https

Вопрос или проблема

У меня есть две конфигурации – для разработки и предварительного тестирования – с (по идее) идентичными настройками: набор экземпляров Apache только для HTTP, находящихся за балансировщиком нагрузки Citrix, который разрешает как HTTP, так и HTTPS соединения.

Определения VirtualHost Apache содержат следующие директивы:

RedirectMatch permanent /something/endpoint(.*)$ /something/otherendpoint$1
SSLProxyEngine On
ProxyPass /something/endpoint !
ProxyPass /something https://192.168.1.100:6443/something
<Location /something>
ProxyPassReverse https://192.168.1.100:6443/something
</Location>

Я хочу проксировать любые запросы к /something на другой бэкенд HTTPS сервер, кроме /something/endpoint, который мне нужно перенаправить.

На данный момент всё работает хорошо в моей среде разработки. Я могу получить доступ к http://hostname/something/endpoint, и это перенаправит меня на http://hostname/something/otherendpoint. Точно так же я могу получить доступ к https://hostname/something/endpoint, и это перенаправит меня на https://hostname/something/otherendpoint.

Но в среде предварительного тестирования оба запроса http://hostname/something/endpoint и https://hostname/something/endpoint перенаправляют на http://hostname/something/otherendpoint – не сохраняется HTTPS.

Я рву на себе волосы, пытаясь понять, в чем разница между двумя конфигурациями. Должно быть что-то, что заставляет Apache не учитывать протокол доступа, но я не могу это изолировать. Заголовки ответов HTTP выглядят одинаково в обеих средах, кроме заголовка перенаправления Location, который указывает http вместо https.

Есть идеи, что могло бы вызвать эту разницу в конфигурациях?

Пожалуйста, помните, что постоянные перенаправления кэшируются вашим веб-браузером, вам нужно либо вручную очищать кэш браузера после каждого теста/изменения в вашей конфигурации, либо тестировать в «инкогнито» или «анонимных» окнах браузера.

То, как apache httpd объединяет директивы конфигурации, может быть немного запутанным.
Синтаксис, который вы используете, кажется немного непоследовательным и может быть причиной ваших проблем:

ProxyPass /something https://192.168.1.100:6443/something
<Location /something>
ProxyPassReverse https://192.168.1.100:6443/something
</Location> 

Чтобы прояснить, пожалуйста, используйте либо:

ProxyPass /something/endpoint !
ProxyPass /something https://192.168.1.100:6443/something
ProxyPassReverse /something https://192.168.1.100:6443/something

либо заключите всё в директивы Location:

<Location /something>
  ProxyPass  https://192.168.1.100:6443/something
  ProxyPassReverse https://192.168.1.100:6443/something
</Location>
<Location /something/endpoint>
  ProxyPass  "!"
  Redirect permanent /something/otherendpoint
</Location>

Ответ или решение

Судя по вашему описанию, проблема заключается в том, что в конфигурации в staging-окружении редирект с HTTPS не сохраняет протокол при выполнении перенаправления. Возможно, это связано с тем, что сервер Apache не получает корректную информацию о том, что соединение было установлено по протоколу HTTPS.

  1. Проверьте настройки прокси-сервера (Citrix Load Balancer): Убедитесь, что ваш балансировщик нагрузки корректно передает информацию о протоколе клиентскому соединению в заголовках. Для этого можно использовать заголовок X-Forwarded-Proto, который указывает, через какой протокол произошло первоначальное соединение (HTTP или HTTPS). Убедитесь, что балансировщик нагрузки настроен на добавление этого заголовка правильно.

  2. Измените конфигурацию Apache: В вашем случае, чтобы сохранить HTTPS при редиректе, вы можете использовать заголовок X-Forwarded-Proto. Будет полезно сделать следующее:

    # Включите модуль для извлечения заголовков
    RemoteIPHeader X-Forwarded-For
    RemoteIPTrustedProxy <IP адрес вашего балансировщика нагрузки>
    
    # Настройки для виртуального хоста
    <VirtualHost *:80>
       RedirectMatch permanent /something/endpoint(.*)$ /something/otherendpoint$1
    </VirtualHost>
    
    <VirtualHost *:443>
       SSLEngine On
       # Другие SSL настройки...
    
       # Ваши директивы
       ProxyPass /something/endpoint !
       ProxyPass /something https://192.168.1.100:6443/something
       <Location /something>
           ProxyPassReverse https://192.168.1.100:6443/something
       </Location>
    </VirtualHost>
  3. Измените директивы RedirectMatch: В секции, отвечающей за запреты (ProxyPass), используйте условие в редиректе, чтобы базироваться на X-Forwarded-Proto:

    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} https
    RewriteRule ^/something/endpoint(.*)$ https://%{HTTP_HOST}/something/otherendpoint$1 [R=301,L]
  4. Очистка кэша браузера: Не забывайте, что браузеры кэшируют 301 редиректы. Поэтому после внесения изменений в конфигурацию вам может понадобиться очистить кэш браузера или использовать режим инкогнито для тестирования.

  5. Проверка и отладка: Используйте инструменты, такие как curl, чтобы просмотреть заголовки ответа и убедиться, что заголовок X-Forwarded-Proto передается корректно:

    curl -I https://hostname/something/endpoint

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

Оцените материал
Добавить комментарий

Капча загружается...