Вопрос или проблема
У меня есть две конфигурации – для разработки и предварительного тестирования – с (по идее) идентичными настройками: набор экземпляров 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.
-
Проверьте настройки прокси-сервера (Citrix Load Balancer): Убедитесь, что ваш балансировщик нагрузки корректно передает информацию о протоколе клиентскому соединению в заголовках. Для этого можно использовать заголовок
X-Forwarded-Proto
, который указывает, через какой протокол произошло первоначальное соединение (HTTP или HTTPS). Убедитесь, что балансировщик нагрузки настроен на добавление этого заголовка правильно. -
Измените конфигурацию 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>
-
Измените директивы
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]
-
Очистка кэша браузера: Не забывайте, что браузеры кэшируют 301 редиректы. Поэтому после внесения изменений в конфигурацию вам может понадобиться очистить кэш браузера или использовать режим инкогнито для тестирования.
-
Проверка и отладка: Используйте инструменты, такие как
curl
, чтобы просмотреть заголовки ответа и убедиться, что заголовокX-Forwarded-Proto
передается корректно:curl -I https://hostname/something/endpoint
Если после выполнения всех этих шагов проблема не исчезнет, лучше всего будет проверить логи сервера Apache на предмет ошибок и просмотреть конфигурацию балансировщика нагрузки на предмет правильности обработки HTTPS-запросов.