리버스 프록시로 상대 URL을 올바르게 처리하는 방법


51

Apache에서 다음과 같이 리버스 프록시 설정이 있습니다.

주소가 www.example.com/folder 인 서버 A는 리버스 프록시 서버입니다.

주소가 test.madeupurl.com 인 서버 B에 맵핑됩니다.

이런 종류의 작품. 그러나 내가 가진 문제는 www.example.com/folder에서 모든 상대 링크가 www.example.com/folder/css/examplefilename이 아닌 www.example.com/css/examplefilename.css 형식이라는 것입니다. CSS

이 문제를 어떻게 해결합니까?

지금까지 내 역방향 프록시는 서버 A (www.example.com)에 있습니다.

<Location /folder>
    ProxyPass  http://test.madeupurl.com
    ProxyPassReverse http://test.madeupurl.com
</Location>

HBruijn의 답변에서 아래 중 어떤 솔루션이 도움이 되었습니까?
Kimberly W

답변:


81

Apache ProxyPassRewrite는 http://test.example.com 에서 수신 한 응답 본문을 다시 쓰지 않고 헤더 만 (404 페이지로 리디렉션하는 등) 다시 작성합니다 .

여러 대안 :

하나 ) 절대 대신 상대 경로를 사용하도록 내부 앱을 다시 작성하십시오. 즉 ../css/style.css대신/css/style.css

2 ) /foldertest.example.com의 루트가 아닌 동일한 하위 디렉토리에 내부 앱을 재배치합니다 .

3 ) 1과 2는 종종 발생하지 않을 것입니다 ... 운이 좋으면 내부 앱이 2 개 또는 3 개의 하위 디렉토리 만 사용 하고 기본 사이트 에서 사용되지 않는 하위 디렉토리 를 사용하는 경우 간단히 ProxyPass 행을 작성하십시오.

# Expose Internal App to the internet.
ProxyPass /externalpath/  http://test.example.com/
ProxyPassReverse /externalpath/  http://test.example.com/
# Internal app uses a bunch of absolute paths. 
ProxyPass /css/  http://test.example.com/css/
ProxyPassReverse /css/  http://test.example.com/css/
ProxyPass /icons/  http://test.example.com/icons/
ProxyPassReverse /icons/  http://test.example.com/icons/

Four ) 내부 앱에 대해 별도의 하위 도메인을 만들고 모든 것을 리버스 프록시하십시오.

<VirtualHost *:80>
   ServerName app.example.com/
   # Expose Internal App to the internet.
   ProxyPass /  http://test.internal.example.com/
   ProxyPassReverse /  http://test.internal.example.com/
</VirtualHost>

5 ) 개발자 는 전혀 단서 가없고 응용 프로그램에서 절대 URL을 생성 할뿐 아니라 URL에 호스트 이름 부분을 포함 시키며 결과 HTML 코드는 다음과 같습니다 <img src=http://test.example.com/icons/logo.png>.

A ) 수평 분할 DNS 및 시나리오 4의 콤보 솔루션을 사용할 수 있습니다. 내부 및 외부 사용자 모두 test.example.com을 사용하지만 내부 DNS는 test.example.com 서버의 ip-address를 직접 가리 킵니다. 외부 사용자의 경우 test.example.com의 공개 레코드는 공개 웹 서버 www.example.com의 ip 주소를 가리키고 솔루션 4를 사용할 수 있습니다.

B ) 실제로 test.example.com에 대한 프록시 요청뿐만 아니라 응답 본문이 사용자에게 전송되기 전에 다시 작성할 수 있습니다. 일반적으로 프록시는 HTTP 헤더 / 응답 만 다시 작성합니다. 아파치의 mod_substitute 2.2. mod_proxy와 제대로 스택되는지 테스트하지는 않았지만 다음과 같이 작동합니다.

<Location /folder/>
  ProxyPass http://test.example.com/
  ProxyPassReverse http://test.example.com/ 
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|test.example.com/|www.example.com/folder/|i" 
</Location>

4
이런 소 좋은 대답. 이 중 아무 것도 시도하지 않았지만 쓰기에 감사를 표하고 싶었습니다! 백만을 도와줍니다. 이 아이디어 중 일부를 지금 시험 해보고 곧 다시보고 할 것입니다 :)
열심히 일하는

내가 당신을 올바르게 이해하고 있다면 포인트 2에 대한 빠른 질문을하십시오 .adpp를 test.madeupurl.com/folder에 재배치 하시겠습니까? 아파치 설정 파일을 변경해야합니까? 이것은 가장 빠른 해결책처럼 보입니다
열심히 일하는 사람

또한 귀찮게해서 죄송하지만 질문에 설명 한 문제를 제안 할 때 포인트 1을 유지하면 여전히 지속됩니다. 예를 들어 여기서는 <link rel = "stylesheet"type = "text / css"href = "../ css / custom.css"/>를 사용했으며 브라우저의 링크 주소에 대해 test.madeupurl.com을 출력 합니다. test.madeupurl.com/folder/css/bootstrap.css 대신 /css/bootstrap.css 입니다. 가장 도움이 될만한 제안이 있으신가요?
열심히 일하는

DocumentRoot에 현재 설치된 응용 프로그램을 / folder와 같은 하위 디렉토리에 재배포 할 때 스타일 시트, 아이콘 등이 / folder / css 및 / folder / icons 등에 배포됩니다. 그러면 HTML 출력의 링크가 다음과 같이 <img src=/folder/icons/button.png>됩니다. ProxyPass /folder/ http://test.madeupurl.com/folder/지시에 따라 회전 합니다.
HBruijn

test.madeupurl.com/content/index.html 페이지에 test.madeupurl.com/css/custom.css를 포함하려고합니다. 해당 위치에서는 href="../css/custom.css"아닌 상대 URL을 사용해야합니다 href="/css/custom.css". 인터넷 사용자가 페이지를 검색하면 URL은 www.example.com/folder/content/index.html이됩니다. 그러면 CSS의 URL은 다음과 같습니다. www.example.com/folder/content/../css/custom.css실제로 www.example.com/folder/css/custom.css는로 전달됩니다 test.madeupurl.com/css/custom.css.
HBruijn

8

HBruijn 의 답변을 보완하기 위해 솔루션 (3) "ProxyPass" 를 선택하는 경우 HTML 페이지에서 일부 URL을 다시 작성 하기 위해 mod_proxy_html 을 사용해야 할 수도 있습니다 .

cf. 일부 예 에서 리버스 프록시상대 URL을 올바르게 처리하는 방법 .

인가 예를 들어, 여기 당신이 사용하는 아파치를 구성하는 방법이다 ProxyHTMLURLMap에서 모든 것을 전달하는 규칙을 your-domain-name.com/pad을 당신에 Etherpad의 포트 9001에서 로컬로 실행중인 인스턴스 :

<Location /pad> ProxyPass http://localhost:9001 retry=0 # retry=0 => avoid 503's when restarting etherpad-lite ProxyPassReverse http://localhost:9001 SetOutputFilter proxy-html ProxyHTMLURLMap http://localhost:9001 </Location> RewriteRule ^/pad$ /pad/ [R]


2
mod_proxy_html은 Apache 2.4 이상에서만 포함되지만 위의 원래 질문은 Apache 2.2에 대한 것입니다.
HBruijn

당신의 대답은 완벽합니다. 그러나 내용이 html이 아닌 pdf 인 경우를 만났습니다. ProxyHTMLURLMap 사용이 작동하지 않았습니다. 다른 제안?
Mohamed Ennahdi El Idrissi

2
컨텐츠가 PDF 인 경우 URL을 다시 작성할 필요가 없습니다! 사용자가 PDF의 링크를 클릭하여 웹 사이트의 다른 페이지에 액세스하도록하려는 것이 아니라면 까다로울 수 있습니다. URL 재 작성을 비활성화하려면 마지막 2 개의 지시문을 생략하면됩니다 : SetOutputFilter& ProxyHTMLURLMap.
Lucas Cimon

당신은 추가해야 할 수도 있습니다 에 RequestHeader 해제 수락 - 인코딩 인코딩 오류를 피하기 위해
zar3bski

5

다음 방법을 사용하여 리버스 프록시를 만들 수 있습니다.
1. mod_proxy_html을 설치하십시오.

    yum install mod_proxy_html
  1. mod_proxy_html 모듈로드

    LoadModule proxy_html_module modules/mod_proxy_html.so
    
  2. 다음 설정을 사용하십시오.

    ProxyRequests off  
    ProxyPass /folder/  http://test.madeupurl.com  
    ProxyHTMLURLMap http://test.madeupurl.com  /folder  
    
    <Location /folder/>  
        ProxyPassReverse /  
        ProxyHTMLEnable On  
        ProxyHTMLURLMap  /  /folder/  
        RequestHeader    unset  Accept-Encoding  
    </Location>  
    

이 도움을 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.