# [ 살펴보기 ] Nginx - Proxy module

Nginx는 static file을 response로 제공하는 static file web server의 역할 뿐만 아니라 client의 request를 실행되고 있는 backend application로 전달 해주고 backend application에서 처리된 response를 다시 client에 전달해주는 reverse proxy의 역할도 할 수 있다.

만약 nodejs application이 3000 port에서 실행 중이고 nodejs application을 통해 실제 request를 처리하고자 한다면 nginx는 client가 보내는 request를 nodejs application으로 전달해주어야 하는데 이러한 기능을 제공하는 module이 proxy module이다.

아래는 example.com으로 들어온 request를 localhost:3000으로 전달해주기 위한 간단한 예시다.

```nginx
server {
     listen 443 ssl;
     listen [::]:443 ssl;
     include snippets/self-signed.conf;
     include snippets/ssl-params.conf;

     server_name example.com

     location / {
        proxy_pass http://localhost:3000;
     }
}
```

proxy\_pass이외에 proxy module이 제공하는 directive는 다양하며 해당 포스트에선 proxy module의 일부를 살펴본다. 전체 directive list는 documentation에서 확인할 수 있다. ( *Reference* - [ngx\_http\_proxy\_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) )

Proxy module directive 예제를 설명하며 나오는 용어 중 proxied serve는 위에서 언급한 예시를 기준으로 nodejs backend server를 뜻한다.

* proxy\_pass : request가 전달되어야 할 location을 정한다. location block에서 사용할 수 있으며 위에서 언급된 nodejs 예제를 기준으로 다음과 같이 설정할 수 있다.
    
    ```nginx
    proxy_pass http://localhost:3000;
    ```
    
* proxy\_pass\_request\_body : client에서 전달된 request의 body를 backend server에 전달할지 여부를 설정할 수 있다. default 값은 on이며 http, server, location block에서 설정할 수 있다.
    
    ```nginx
    proxy_pass_request_body on;
    ```
    
* proxy\_pass\_request\_headers : client에서 전달된 request의 header를 backend server에 전달할지 여부를 설정할 수 있다. default 값은 on이며 http, server, location block에서 설정할 수 있다.
    
    ```nginx
    proxy_pass_request_headers on;
    ```
    
* proxy\_hide\_header : backend server의 response를 nginx가 다시 client로 전달할 때 함께 전달하지 않을 http header를 설정한다. 다음과 같이 설정하면 response에서 Last-Modified header를 제외하고 client에 전달한다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_hide_header Last-Modified;
    ```
    
* proxy\_pass\_header : nginx는 default로 backend server의 response에서 Date, Server, X-Pad X-Accel-\* http header는 제외하고 client로 전달한다. proxy\_pass\_header directive를 통해 client로 전달되어야 하는 header를 설정할 수 있다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_pass_header Date;
    ```
    
* proxy\_method : client에서 전달된 reqeust의 method를 override할 수 있다. 예를 들어 다음과 같이 설정하면 client에서 전달된 모든 request의 method는 get으로 override되어 backend server로 전달된다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_method GET;
    ```
    
* proxy\_redirect : backend server에서 redirection response가 발생했을 때 response의 Location header를 다른 값으로 변경할 때 사용할 수 있는 directive다. default value는 default이며 http, server, location block에서 사용할 수 있다.
    
    ```nginx
    
    proxy_redirect default; # default value
    # proxy_pass에 설정한 값으로 redirection response의 location header를 설정한다.
    
    proxy_redirect off;
    # backend server에서 설정한 redirection location을 변경하지 않는다
    
    proxy_redirect http://localhost:3000/admin/ http://frontapp/member/;
    # 만약 위와 같이 설정하고 redirection location이 http://localhost:3000/admin/items 이라면
    # 다음과 같이 변경된다 http://frontapp/member/items
    ```
    
* proxy\_connect\_timeout : proxied server connection timeout을 설정한다. 설정하는 단위는 seconds이며 default 는 60s다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_connect_timeout 60;
    ```
    
* proxy\_read\_timeout : proxied server로 보낸 request에 대한 response timeout을 설정한다. nginx server와 proxied server 사이에서 발생하는 operation에 대한 timeout이며 전체 client request - response에 대한 timeout 설정은 아님에 주의하자. seconds 단위로 설정하고 default는 60s다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_read_timeout 60;
    ```
    
* proxy\_send\_timeout : nginx server에서 proxied server로 client request를 전달할 때의 timeout을 설정한다. nginx server와 proxied server 사이에서 발생하는 operation에 대한 timeout이며 전체 client request - response에 대한 timeout 설정은 아님에 주의하자. seconds 단위로 설정하고 default는 60s다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_send_timeout 60;
    ```
    
* proxy\_ignore\_client\_abort : client에서 request를 abort할 때 nginx도 proxied server와 connection을 종료할지 여부를 설정할 수 있다. on으로 설정하면 client에서 request를 abort할 지라도 nginx는 request를 원래대로 proxied server로 전달하여 처리하고 off이면 client request가 abort되면 nginx 역시 해당 request에 대한 proxed server와의 connection을 종료한다. default는 off이며 http, server, location block에서 사용 할 수 있다.
    
    ```nginx
    proxy_ignore_client_abort off;
    ```
    
* proxy\_intercept\_errors : proxied server의 response가 400이거나 400이상일 때 proxied server의 response를 그대로 client로 보낼지 혹은 nginx에서 intercept하여 error\_page directive에 설정된 설정 값에 따라 처리할지 여부를 결정한다. 설정 값이 off일 때 proxied server의 response를 그대로 보내고 on으로 설정하면 nginx에서 intercept하여 errro\_page directive 설정에 따라 response를 보낸다. default는 off며 http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_intercept_errors off;
    ```
    
* proxy\_limit\_rate : Proxied server로 부터 response를 read하는 속도를 제한한다. 초당 bytes 단위로 설정하며 0으로 설정하면 limit을 적용하지 않는다. rate limit은 개별 request에 적용되며 default 값은 0이다. http, server, location block에서 사용할 수 있다. proxied server response에 대한 proxy\_buffering directive가 활성화 된 상태에서만 적용된다\*\*.\*\*
    
    ```nginx
    proxy_limit_rate 0;
    ```
    
* proxy\_ignore\_headers : proxied server의 response 중 특정 header를 nginx가 무시하도록 설정할 수 있다. proxy\_ignore\_headers directive를 통해 다음 header는 무시할 수 있다. `X-Accel-Redirect, X-Accel-Expires, X-Accel-Limit-Rate, X-Accel-Buffering, X-Accel-Charset, Expires, Cache-Control, Set-Cookie, and Vary`. Default는 따로 설정되어 있지 않으며 http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_ignore_headers X-Accel-Redirect;
    ```
    
* proxy\_set\_body : proxied server로 client request를 전달할 때 request body를 재설정하여 전달할 수 있다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_set_body '{"address":"test address", "city":"seoul"}';
    ```
    
* proxy\_set\_header : proxied server로 client request를 전달할 때 request header에 새로운 field를 추가하거나 재설정하여 전달할 수 있다. 만약 현재 block에 선언되어 있는 `proxy_set_header`가 없고 상위 block에서 `proxy_set_header`를 선언하여 사용하고 있다면 상위 block에서 사용한 `proxy_set_header`의 설정 값이 하위 block에도 적용된다.
    
    default로 아래 두 header가 예제와 같이 재설정된다.
    
    ```nginx
    proxy_set_header Host $proxy_host;
    proxy_set_header Connection close;
    ```
    
    caching 기능이 활성화 되어 있을 때 client request의 header중 다음 header fields는 proxied server로 전달되지 않는다.
    
    `If-Modified-Since, If-Unmodified-Since, If-None-Match, If-Match, Range, and If-Range`
    
    만약 host header로 client request의 host header 정보를 그대로 사용하고 싶다면 `proxy_set_header`directive를 `proxy_set_header Host $host;`로 설정한다.
    
    $http\_host variable은 client request의 host header가 없으면 proxied server로 전달되는 host header가 빈 값이 될 수 있지만 $host variable은 다음 순서로 체크하며 먼저 발견되는 값을 사용한다 : hostname from request line → request의 host header field → server\_name directive에 설정한 값 ( request를 처리하는 server block의 server\_name )
    
    ```nginx
    proxy_set_header Host $host;
    ```
    
    다음과 같이 설정하면 port 정보로 함께 설정할 수 있다.
    
    ```nginx
    proxy_set_header Host $host:$proxy_port;
    ```
    
    만약 header의 값이 empty string이면 해당 header는 proxied server로 전달되지 않는다.
    
    ```nginx
    proxy_set_header Accept-Encoding "";
    ```
    
* proxy\_headers\_hash\_bucket\_size **:** proxy\_hider\_header와 proxy\_set\_header에 사용되는 hash table의 bucket size를 설정한다. default는 64이며 http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_headers_hash_bucket_size 64;
    ```
    
* proxy\_headers\_hash\_max\_size : proxy\_hider\_header와 proxy\_set\_header에 사용되는 hash table의 size를 설정한다. default는 512이며 http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_headers_hash_max_size 512;
    ```
    
* proxy\_http\_version : proxied server와 connection에 사용될 http version을 설정한다. default는 1.0이며 keepalive connection에는 1.1로 설정하는 것이 권장된다.
    
    ```nginx
    proxy_http_version 1.0;
    ```
    
* proxy\_cookie\_domain : proxied server response의 Set-Cookie에 설정된 cookie의 domain attribute를 지정한 값으로 다시 설정해 client로 전달할 수 있다. 만약 cookie의 domain attribute가 `domain=test.com`으로 설정되어 있다면 다음 예제는 domain attribute를 `domain=example.com`으로 변경하여 client에 전달한다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_cookie_domain test.com example.com;
    ```
    
    default값은 off이며 만약 off로 설정되어 있으면 상단 block에서 설정된 proxy\_cookie\_domain directive 값은 현재 block에 적용되지 않는다.
    
    ```nginx
    proxy_cookie_domain off;
    ```
    
* proxy\_cookie\_path : proxied server response의 Set-Cookie에 설정된 cookie의 path attribute를 지정한 값으로 다시 설정해 client로 전달할 수 있다. 만약 cookie의 path attribute가 path=/admin/detail로 설정되어 있다면 다음 예제는 path attribute를 path=/member/detaul로 변경하여 client로 전달한다. http, server, location block에서 사용할 수 있다.
    
    ```nginx
    proxy_cookie_path /admin/detail /member/detail;
    ```
    
    default 값은 off이며 만약 off로 설정되어 있으면 상단 block에서 설정된 proxy\_cookie\_path directive 값은 현재 block에 적용되지 않는다.
    
    ```nginx
    proxy_cookie_path off;
    ```
    

## Proxy module variables

* $proxy\_host : proxy\_pass에 설정한 proxied server의 name과 port 정보
    
* $proxy\_port : proxy\_pass에 설정한 proxied server의 port 정보
    
* $proxy\_add\_x\_forwarded\_for : client request의 `X-Forwarded-For` header value에 `$remote_addr` header value를 추가한 값. client request에 `X-Forwarded-For` header가 없으면 `$proxy_add_x_forwarded_for`는 `$remote_addr`value와 동일하며 `X-Forwarded-For` header value와 `$remote_addr` value가 모두 있으면 두 값 사이에 comma가 추가된다.
