
Я настроил конфигурацию Apache, чтобы попытаться перенаправить /login
и пропустить через ProxyPass все остальные запросы:
RewriteEngine on
RewriteCond "%{REQUEST_URI}" "^/login$"
RewriteRule "^/login$" "https://sub.example.org/$1" [L,R]
SSLProxyEngine on
ProxyRequests off
ProxyPassMatch ^/login ! # Prevent proxy on /login
ProxyPassReverse ^/login ! # Prevent proxy on /login
ProxyPassMatch ^/ https://sub.example.org/
ProxyPassReverse ^/ https://sub.example.org/
ProxyPreserveHost off
RequestHeader set Host sub.example.org
Header set Host alt.example.org
Большинство проверенных мной результатов соответствуют моим ожиданиям:
- alt.example.org/login перенаправляет на sub.example.org/login
- alt.example.org/users показывает содержимое для sub.example.org/users (без редиректа)
...ноhttps://alt.example.org/(пустой путь) приводит к Location
заголовку со значением https://alt.example.org^/login
. Ого! Что вызывает это перенаправление с ^
доменом и почему оно ссылается alt
на вместо sub
?
Журнал приложения Rails, работающего поверх Apache, показывает, что само приложение Rails на самом деле перенаправляет наhttps://sub.example.org/login, что имеет смысл, поскольку ProxyPass означает, что Rails должен видеть только sub.example.org, а не alt.example.org. Так почему же apache выдает https://alt.example.org^/login?
решение1
...но
https://alt.example.org/
(пустой путь) приводит кLocation
заголовку со значениемhttps://alt.example.org^/login
. Ого! Что вызывает это перенаправление с^
в домене, и почему оно ссылается на alt вместо sub?
Директива ProxyPassReverse
не принимает регулярное выражение в качестве первого аргумента, и, похоже, именно здесь и происходит конфликт. И это не может быть принято !
в качестве второго аргумента. alt
Поддомен появится в Location
заголовке, если ProxyPassReverse
директива не соответствует ответу.
Похоже, вам не нужна первая ProxyPassReverse
директива, относящаяся к /login
, поскольку этот URL не проксируется.
Кроме того, эти ProxyPassMatch
директивы, по-видимому, проксируют все в корень https://sub.example.org/
- вы не хотите проксировать на соответствующий URL-путь в целевом домене? Хотя, как ни странно, это, похоже, происходит в ваших наблюдаемых результатах? Если вы хотите проксировать на тот же URL-путь, то вы можете использовать более простую ProxyPass
директиву и использовать простое сопоставление префиксов вместо регулярного выражения.
alt.example.org/login
перенаправляет наsub.example.org/login
Хотя это не выполняется «перенаправлением», которое вы разместили вверху, которое перенаправит в корень документа, поскольку обратная $1
ссылка пуста, поскольку в подшаблоне захвата нетRewriteRule
шаблон. Как вы позже утверждаете, «само приложение Rails на самом деле перенаправляет на https://sub.example.org/login
».
Итак, чтобы выполнить перенаправление sub.example.org/login
(что, по-видимому, и было задумано), вам нужно будет изменить директиву следующим образом:
RewriteRule ^/(login)$ https://sub.example.org/$1" [R,L]
Предыдущая RewriteCond
директива здесь не требуется, поскольку она просто повторяет ту же проверку, которую вы уже выполнили вRewriteRule
шаблон.
RequestHeader set Host sub.example.org
Эта строка лишняя, поскольку именно для этого предназначена предыдущая ProxyPreserveHost off
директива.
Header set Host alt.example.org
Эта строка также может показаться избыточной, поскольку Host
является заголовком запроса, а не заголовком ответа.
ProxyPassMatch ^/login ! # Prevent proxy on /login
Также Apache не поддерживает комментарии конца строки. Только из-за "причуды" в способе обработки директив Apache этот конкретный комментарий конца строки не позволяет сломать ваш сервер!
Поэтому, принимая во внимание вышеизложенные пункты, попробуйте сделать следующее:
RewriteEngine on
# Externally Redirect "/login" to other domain
RewriteRule ^/(login)$ https://sub.example.org/$1" [R,L]
SSLProxyEngine on
ProxyRequests off
ProxyPreserveHost off
# Prevent proxy on /login
ProxyPass /login !
# Proxy all other URLs
ProxyPass / https://sub.example.org/
ProxyPassReverse / https://sub.example.org/