본문 바로가기
Nginx

rewrite break 이슈

by ybs 2022. 2. 17.
반응형

만약 http://ybs.com/hello/world 요청을 nginx 서버가 받고 뒷단 서버(proxied server 또는 downstream server) 에 /world 경로만 전달해주고 싶다면 2가지 방법이 있다.

 

방법1 : rewrite + proxy_pass

location /hello/ {

    rewrite ^/hello(/.*)$ $1 break;
    proxy_pass http://server.com;
    
}

 

rewrite 끝에 break flag 를 추가함으로써, 현재 rewrite 규칙이 적용되기는 하지만 nginx 가 수정된 URI 로 새롭게 일치하는 location 을 찾지 않도록 한다. 이후의 모든 rewrite 지시어는 무시된다.

 

방법2 : location 끝에 /(slash) 를 추가하고 proxy_pass 끝에 /(slash) 추가한다.

location /hello/ {
    proxy_pass http://server.com/;
}

 

그런데 방법1 로 real_ip 를 추가 전달하던 중 문제가 생겼다. 아래와 같이 xff, xfp 변수를 만들고 http_real_ip 값이 있으면 그값으로 대체하는 로직이다.

location /hello/ {

    rewrite ^/hello(/.*)$ $1 break;
    proxy_pass http://server.com;

    set $xff $proxy_add_x_forwarded_for;
    set $xfp $scheme;

    if ($http_real_ip != '') {
        set $xff $http_real_ip;
        set $xfp $http_forwarded_proto;
    }
    
    proxy_set_header    X-Forwarded-For $xff;    
    proxy_set_header    X-Forwarded-Proto $xfp;

    ... 나머지 생략
}

 

이렇게 실행시키고 디버그 로그를 보면 아래와 같이 xff, xfp 변수가 unititialized 라고 나온다. 실제로 http_real_ip 값이 있어도 X-Forwarded-For, X-Forwarded-Proto 헤더로 전달되지 않았다.

[warn] 23476#0: *109 using uninitialized "xff" variable, client: 127.0.0.1, ...
[warn] 23476#0: *109 using uninitialized "xfp" variable, client: 127.0.0.1, ...

 

rewrite 의 break flag 를 제거하고 실행시키면 아래와 같이 제대로 셋팅된다. 대신 rewrite 로 수정된 URI 로 새롭게 일치하는 location 을 찾으므로 그에 맞는 location 도 준비되어야 한다.

[debug] 24052#0: *115 http script complex value
[debug] 24052#0: *115 http script var: "127.0.0.1"
[debug] 24052#0: *115 http script set $xff
[debug] 24052#0: *115 http script complex value
[debug] 24052#0: *115 http script var: "http"
[debug] 24052#0: *115 http script set $xfp

 

cf) rewrite 지시자를 사용할 때 redirect flag 가 있어야 302로 응답을 주고 브라우저가 다시 요청을 보낸다(301은 permanent flag). 단순히 rewrite 만 있으면 nginx 내부적으로 새로운 URI 로 다시 요청을 보내므로 브라우저는 알 수 없다.

 

그런데 만약 http:// 로 시작하는 새로운 URI를 직정 지정하면 nginx 는 자동으로 redirect flag 를 사용한다. 

rewrite ^ http://ybs.com;

 

rewrite syntax 규칙은 다음과 같다. Syntax: rewrite regex replacement [flag];

replacement 에 정규표현식이 포함되어 있지 않아도 regex 는 필수로 추가해줘야 한다. 안그러면 

nginx: [emerg] invalid number of arguments in "rewrite" directive 라는 nginx 문법 오류가 발생한다.

 

 

참고 : http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

참고 : http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

참고 : https://serverfault.com/questions/379675/nginx-reverse-proxy-url-rewrite

참고 : Nginx HTTP 서버 책 P178

반응형

'Nginx' 카테고리의 다른 글

nginx 수정 하면서 썼던 명령어 정리  (0) 2021.08.03
reset_timedout_connection 옵션  (0) 2021.01.19
timeout 설정 정리  (0) 2021.01.19
파일 업로드/다운로드 시 임시 디렉토리 권한 이슈  (0) 2021.01.19
nginx gzip 옵션  (0) 2021.01.17