nginx proxy_pass로 요청 URL을 보존하는 방법


80

Thin 앱 서버 를 사용하려고 했는데 한 가지 문제가있었습니다.

nginx 가 애플리케이션을 사용하여 Thin (또는 Unicorn)에 대한 요청을 프록시 할 때 nginx proxy_pass http://my_app_upstream;( http://my_app_upstream)가 보낸 수정 된 URL을 수신합니다 .

내가 원하는 것은 앱이 그것에 크게 의존하기 때문에 수정하지 않고 클라이언트의 원래 URL과 원래 요청을 전달하는 것입니다.

nginx의 문서 는 다음과 같이 말합니다.

처리되지 않은 형식으로 URI를 전송해야하는 경우 URI 부분없이 proxy_pass 지시문을 사용해야합니다.

하지만 관련 샘플이 실제로 URI를 사용하고 있으므로 정확히 구성하는 방법을 이해하지 못합니다.

location  /some/path/ {
  proxy_pass   http://127.0.0.1;
}

클라이언트 의 원래 요청 URL보존하는 방법을 알아 내도록 도와 주 시겠습니까?

답변:


135

proxy_set_header지침이 도움이 될 수 있다고 생각합니다 .

location / {
    proxy_pass http://my_app_upstream;
    proxy_set_header Host $host;
    # ...
}

92
이 사실을 발견 한 다른 사람들을 참고하십시오. nginx가 URL을 조작하지 않도록하는 솔루션의 핵심은 proxy_pass지시문 끝에서 슬래시를 제거하는 것 입니다. http://my_app_upstreamhttp://my_app_upstream/
휴고 Josefson

2
나에게 일어난 일은 JSP가 리디렉션을 수행 할 때 my_app_upstream 호스트 이름이 표시되었다는 것입니다. proxy_set_header Host $host수정하고 만든 Tomcat / JSP를 사용 하여 실제 클라이언트가 요청한 도메인이라고 생각합니다. 도움을 주셔서 감사합니다
ankitjaininfo

1
@HugoJosefson 와우 감사합니다. 이것은 대답에 명시되어야합니다
plus-

3
제 경우에는 @HugoJosefson의 솔루션이 작동하지 않습니다. 나는 localhost : port를 가리키고 있었다 ; 헤더를 설정해야했습니다.

2
개선되었지만 체계 (http 또는 https)는 보존되지 않습니다. 이제 내 https://example.com/pageuris가됩니다http://example.com/page
John Smith Optional

11

제 경우에는 proxy_set_header 호스트 $ host 미스 포트만 있습니다. 해결 방법 :



    location / {
     proxy_pass http://BACKENDIP/;
     include /etc/nginx/proxy.conf;
    }

그런 다음 proxy.conf에서



    proxy_redirect off;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


1
감사합니다. 이것은 프록시 뒤의 엔드 포인트에서 OAuth 확인 작업을 수행하기 위해 누락 된 부분 ($ server_port)이었습니다.
renier 2014

sinatra와 함께 랙 보호를 사용하고 있으며 POST URL에서 금지되었습니다. 호스트 프록시 헤더에 포트를 추가하면 문제가 해결되었습니다.
pduey

이것은 Nginx의 최신 버전에서 더 이상 작동하지 않습니다. stackoverflow.com/questions/31482796/…
iwein

4

nginx는 또한 포트를 전달할 $ http_host 변수를 제공합니다. 호스트와 포트의 연결입니다.

그래서 당신은 다음을 수행해야합니다.

proxy_set_header Host $http_host;



3

예를 들어 try_files, 서비스하려는 위치를 수정하는 경우 백엔드에 대한 요청이 유지됩니다.

location / {
  proxy_pass http://127.0.0.1:8080$request_uri;
}

2

내 시나리오에서는 nginx vhost 구성에서 아래 코드를 통해 이것을 만들었습니다.

server {
server_name dashboards.etilize.com;

location / {
    proxy_pass http://demo.etilize.com/dashboards/;
    proxy_set_header Host $http_host;
}}

$ http_host는 요청 된 것과 동일한 헤더에 URL을 설정합니다.


-1

내 인증 서버의 경우 ... 작동합니다. 나는 인간화 된 가독성을 위해 / auth에 대한 옵션을 갖고 싶습니다 ... 또는 기계 대 기계를 위해 포트 / 업스트림으로 구성했습니다.

.

conf의 시작 부분

####################################################
upstream auth {
    server 127.0.0.1:9011 weight=1 fail_timeout=300s;
    keepalive 16;
  }

내 443 서버 블록 내부

          if (-d $request_filename) {
          rewrite [^/]$ $scheme://$http_host$uri/ permanent;
      }

  location /auth {
          proxy_pass http://$http_host:9011;
          proxy_set_header Origin           http://$host;
          proxy_set_header Host             $http_host:9011;
          proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header Upgrade          $http_upgrade;
          proxy_set_header Connection       $http_connection;
          proxy_http_version 1.1;
      }

conf의 맨 아래

#####################################################################
#                                                                   #
#     Proxies for all the Other servers on other ports upstream     #
#                                                                   #
#####################################################################


#######################
#        Fusion       #
#######################

server {
    listen 9001 ssl;

#############  Lock it down  ################

# SSL certificate locations
    ssl_certificate /etc/letsencrypt/live/allineed.app/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/allineed.app/privkey.pem;

# Exclusions

    include snippets/exclusions.conf;

# Security

    include snippets/security.conf;
    include snippets/ssl.conf;

# Fastcgi cache rules

    include snippets/fastcgi-cache.conf;
    include snippets/limits.conf;
    include snippets/nginx-cloudflare.conf;

###########  Location upstream ##############

    location  ~ / {
        proxy_pass http://auth;
        proxy_set_header Origin           http://$host;
        proxy_set_header Host             $host:$server_port;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Connection       $http_connection;
        proxy_http_version 1.1;
    }
        if (-d $request_filename) {
        rewrite [^/]$ $scheme://$http_host$uri/ permanent;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.