Apache ProxyPass + RewriteRule?

Apache ProxyPass + RewriteRule?

Я настроил конфигурацию 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/

Связанный контент