프록시를 통한 Nginx 리디렉션, URL 재 작성 및 유지


71

Nginx에서는 다음과 같이 URL을 리디렉션하려고 시도했습니다.

http://example.com/some/path -> http://192.168.1.24

사용자는 여전히 브라우저에서 원래 URL을 볼 수 있습니다. 사용자가 리디렉션되면에 대한 링크를 클릭한다고 /section/index.html하면 리디렉션으로 연결되는 요청을 할 수 있습니다.

http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html

다시 원래 URL을 유지합니다.

우리의 시도는 프록시와 다시 쓰기 규칙을 사용하는 다양한 솔루션을 포함했으며 아래는 솔루션에 가장 근접한 구성을 보여줍니다 (웹 서버의 웹 서버 구성 example.com임). 그러나이 문제에는 여전히 두 가지 문제가 있습니다.

  • 웹 서버가 수신 한 요청 URL 에 필요한 페이지가 http://192.168.1.24포함되어 있지 않으므로 다시 쓰기가 제대로 수행되지 않습니다 /some/path.
  • 페이지가 제공되면 링크를 가리키면 /some/pathURL에서 누락됩니다

    server {
        listen          80;
        server_name     www.example.com;
    
        location /some/path/ {
            proxy_pass http://192.168.1.24;
            proxy_redirect http://www.example.com/some/path http://192.168.1.24;
            proxy_set_header Host $host;
        }
    
        location / {
            index index.html;
            root  /var/www/example.com/htdocs;
        }
    }
    

웹 서버 구성 만 변경하는 솔루션을 찾고 있습니다 example.com. 우리는 설정을 변경할 192.168.1.24수도 있지만 (Nginx) 액세스를 프록시하는 수백 대의 다른 서버에 대해이 설정을 반복해야하기 때문에 이것을 피하고 싶습니다 example.com.

답변:


59

첫째, root위치 블록 내에서 지시문을 사용해서는 안되며 , 이는 나쁜 습관입니다. 이 경우에는 중요하지 않습니다.

두 번째 위치 블록을 추가하십시오.

location ~ /some/path/(?<section>.+)/index.html {
    proxy_pass http://192.168.1.24/$section/index.html;
    proxy_set_header Host $host;
}

이는 / some / path / 뒤 및 index.html 이전의 부분을 $ section 변수로 캡처 한 다음 proxy_pass 대상을 설정하는 데 사용됩니다. 필요한 경우 정규 표현식을보다 구체적으로 만들 수 있습니다.


1
늦은 답변에 대한 사과-이것은 우리가 찾고있는 것을 달성하는 데 너무 가깝습니다. 유일한 단점은 일단 대상 페이지가 제공되면 브라우저의 링크 URL에 '/ some / path /'가 포함되지 않으므로 사용자가 클릭하면 작동하지 않는다는 것입니다. 우리가 이것을 극복하는 방법을 알아낼 수 있다면 나는 거의 거기에 있기 때문에이 답변을 업데이트하고 받아 들일 것입니다.
robjohncox

8
브라우저가 보는 링크는 192.168.1.24 서버에서 실행되는 소프트웨어에 의해 생성됩니다. 원하는 것을 달성하려면 해당 소프트웨어를 수정해야합니다.
Tero Kilkanen

위치 내부 루트에 대한 경고를 따르지 않습니다. nginx 문서를 읽는 것이 올바른 방법입니다. 그들은 모든 위치 외부에 기본 루트가 없다는 나쁜 습관을 경고합니다. nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
guy mograbi

블록 root내부 에서 사용하지 않는 것이 가장 쉬운 방법이므로 location기본 위치에 대해 예기치 않은 동작이 발생하지 않습니다. root각 위치 의 기본값을 변경해야하는 경우에만 사용할 수 있습니다.
Tero Kilkanen

1
$ host를 이름 으로 받는다는 것은 무엇을 의미 합니까? 전송 된 정확한 HTTP 헤더는 무엇이며 정확하게 보내려는 것은 무엇입니까?
Tero Kilkanen

65

proxy_pass지시문에 URI 부분을 사용해야합니다 . 또한 proxy_redirect지시문의 순서 인수를 혼합하여 필요하지 않을 수도 있습니다. Nginx는이 지시어에 대해 합리적인 기본값을 가지고 있습니다.

이 경우 location블록은 정말 간단 할 수 있습니다.

location /some/path/ {
    proxy_pass http://192.168.1.24/;
    # note this slash  -----------^
    proxy_set_header Host $host;
}

1
늦은 답변에 대한 사과-나는 이것을 시도했지만 불행히도 우리의 유스 케이스에는 작동하지 않습니다. 문제는 요청이 대상 서버에서 이루어질 때 /some/path/URL 의 일부가 유효한 URL이 아닌 요청에 보존된다는 것입니다 (이를 제거하려면 URL을 다시 작성해야 함).
robjohncox

@robjohncox 정확히 무엇을 시도 했습니까?
Alexey Ten

9
슬래시가 나를 위해 속임수를 썼다. 이제 mydomain.com/some/path/*는 192.168.1.24/some이 아닌 192.168.1.24/*로 올바르게 프록시됩니다.
Vadimo

7
이 답변에 "# note this slash"주석을 올릴 수 있습니까? 그 의견에 대한 세 건배!
8one6

이것이 당신 모두에게 어떻게 작동하는지 확실하지 않습니다. 이것이 내가 달성하려고하는 것입니다. 사용자가 로컬 서비스에 192.168.1.24/login하는 예를 재 연결되는 링크를 클릭 할 때, 그는 대신 mydomain.com/some/path/login의 mydomain.com/login로 재
mueslo

4

다음 구성을 사용하여 /some/path/프런트 엔드와 /백엔드 간에 100 % 완벽한 매핑을 수행 할 수 있습니다 .

이것은 브라우저가 404 Not Found올바른 HTTP Referer헤더를 보내면 절대 경로 생성 오류를 완벽하게 처리하는 유일한 대답입니다. 따라서 기본 HTML을 수정할 필요없이 모든 GIF가 계속로드되어야합니다. (비쌀뿐만 아니라 기본적으로 컴파일되지 않은 추가 모듈이 없으면 지원되지 않습니다).

location /some/path/ {
    proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
    error_page 404 = @404;
    return 404; # this would normally be `try_files` first
}
location @404 {
    add_header Vary Referer; # sadly, no effect on 404
    if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
        return 302 $1$uri;
    }
    return 404 "Not Found\n";
}

당신은 찾을 수 있습니다 전체 개념 증명 및 최소한의-가능한-제품https://github.com/cnst/StackOverflow.cnst.nginx.conf의 저장소를.

다음은 모든 엣지 케이스가 작동하는 것으로 확인되는 테스트 실행입니다.

curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer

curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found

curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri:    /and/more.gif

당신이지도하는 다른 경로가 많은 경우 PS, 그럼 대신 정규식 비교를하는 $http_refererif에서 location @404, 전역 기반 사용할 수있는 map대신에 지시합니다.

또한에 포함 된 것 proxy_pass뿐만 아니라에 있는 슬래시도 관련 답변에 따라 매우 중요 합니다.location

참고 문헌 :


2

이 슬래시가 nginx 프록시 젠킨스에 추가되면 "역 프록시 설정이 끊어진 것 같습니다"라는 오류가 표시됩니다.

proxy_pass          http://localhost:8080/;

Remove this -----------------------------^

읽어야한다

proxy_pass          http://localhost:8080;

나는 이것이 OP의 질문이 언급 된 문제와 관련이 있거나 해결 된 것이라고 생각하지 않습니다.
코리 로빈슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.