Apache ProxyPass + RewriteRule?

Apache ProxyPass + RewriteRule?

/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?

Apache 위에서 실행되는 Rails 애플리케이션의 로그에 따르면 Rails 앱 자체가 실제로 다음으로 리디렉션되고 있습니다.https://sub.example.org/loginProxyPass는 Rails가 alt.example.org가 아닌 sub.example.org만 보아야 한다는 것을 의미하기 때문에 이는 더 의미가 있습니다. 그렇다면 Apache가 https://alt.example.org^/login을 제공하는 이유는 무엇입니까?

답변1

...하지만 https://alt.example.org/(빈 경로) Location값이 있는 헤더가 생성됩니다 https://alt.example.org^/login. 우와! 도메인 에서 리디렉션이 발생하는 원인은 무엇 ^이며 왜 sub 대신 alt를 참조합니까?

지시어는 ProxyPassReverse정규식을 첫 번째 인수로 사용하지 않으며 이것이 충돌이 일어나는 곳인 것처럼 보입니다. 그리고 이것도 !두 번째 주장으로 받아들여질 수 없습니다 . 지시문이 응답과 일치하지 않으면 하위 도메인이 헤더 alt에 나타납니다 .LocationProxyPassReverse

이 URL은 프록시되지 않으므로 ProxyPassReverse와 관련된 첫 번째 지시문이 필요하지 않은 것 같습니다 ./login

또한 이러한 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/

관련 정보