OPEN SOURCE/NGINX

[NGINX] forward proxy와 reverse proxy

EARTH_ROOPRETELCHAM 2022. 2. 19. 15:45
728x90
반응형

들어가기 전에

nginx에서 주로 사용되는 reverse proxy 기능과 함께 reverse proxy와 forward proxy간 차이점에 대해 알아보고자 합니다. 

Proxy

proxy

  • Proxy는 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램을 가리킵니다.
  • 서버와 클라이언트 사이에 중계기로서 대리로 통신을 수행하는 것을 proxy라고 합니다. 

Proxy 서버 구축 목적

  1. Speed: proxy 서버는 사용자의 요청을 캐싱하여 동일한 요청이 들어올 경우 캐시된 자원을 반환할 수 있습니다.
  2. ACL: 사이트 접근에 대한 접근 정책을 정의할 수 있습니다.
  3. Security: 중요한 일을 하는 내부 서버에 직접 익명의 사용자가 접근하는 것을 막을 수 있습니다.

Forward Proxy

forward proxy

  • forward proxy란, 클라이언트의 요청이 대상 서버에 직접 전송되지 않고 중간에 proxy 서버를 통해 간접적으로 요청하고 응답을 받아오는 방식을 의미합니다.
  • forward proxy를 통해 정해진 사이트만 연결하도록 제한할 수 있어 보안이 중요한 환경에서 사용됩니다.
  • 위 그림에서처럼 forward proxy 서버는 want.example.com 요청을 받아 타겟 서버로 요청을 중계합니다.

Forward Proxy 사용 용도

  • NAT 용도
  • Content Filtering
  • eMail security

Forward Proxy 구성법

nginx를 forward proxy로 사용하기 위해서는 ngx_http_proxy_connect_module이 필요합니다. ngx_http_proxy_connect_module은 CONNECT 메소드 요청을 지원하며, proxy 서버를 통한 SSL tunneling에 주로 사용됩니다.

  • SSL Tunneling에는 proxy 서버를 통해 클라이언트가 백엔드 서비스나 보안이 중요한 서비스에 SSL 연결하는 것이 포함되어 있습니다. Proxy 서버는 클라이언트와 백엔드 서비스 간 연결을 열고 요청 및 응답을 전송합니다.

ngx_http_proxy_connect_module은 자신의 nginx 버전에 맞게 다운받으면 되고, enable REWRITE phase는 if, set, rewrite_by_lua나 기타 rewrite 구문을 사용해야하는지에 따라 선택하면 됩니다.

  • 만약, rewrite 구문 사용이 필요하다면 YES가 붙은 patch파일을 받아 깔아둔 nginx에 패치하면 됩니다.

https://github.com/chobits/ngx_http_proxy_connect_module

forward proxy 설정 파일 예시

    server {
        listen 3128; # 프록시 서버에 접근할 때 사용할 포트
        server_name [프록시 서버 도메인 또는 IP];

        # dns resolver used by forward proxying
        resolver 8.8.8.8; # 사내 DNS를 통해서 질의를 해야 한다면 사내 DNS 사용 필요

        # forward proxy for CONNECT request
        proxy_connect; # CONNECT HTTP method 허용
        proxy_connect_allow         443 563; # CONNECT method가 연결할 수 있는 포트 리스트(default: 443 563)
        proxy_connect_connect_timeout 120s; # 프록시 서버와의 connection 유지시간
        proxy_connect_read_timeout 120s; # 프록시 서버로부터 응답을 가져올 때의 timeout 시간
        proxy_connect_send_timeout 120s; # 프록시 서버에 요청을 보낼 때의 timeout 시간

        # restrict domain for forward proxy
        if ($http_host !~ "^[실제 통신할 도메인]"){ # 특정 도메인으로만 통신하기 위해 설정
            return 401;
        }

        # forward proxy for non-CONNECT request
        location ~ \.*$ {
            proxy_set_header Host $host;
            proxy_pass $scheme://$host;
        }
    }
  • # restrict domain for forward proxy 부분은 필수는 아니며, forward proxy 서버를 통해 접속할 도메인을 한정 지을 때 사용합니다. 이러한 if문을 사용하기 위해서는 enable REWRITE phase가 YES인 패치 파일을 사용해야 합니다.

하기 내용은 ngx_http_proxy_connect_module github에서 가져온 forward proxy curl 테스트 예시입니다.

https://github.com에 forward proxy 통해 접근할 때의 sequence diagram

$ curl https://github.com/ -v -x 127.0.0.1:3128
*   Trying 127.0.0.1...                                           -.
* Connected to 127.0.0.1 (127.0.0.1) port 3128 (#0)                | curl creates TCP connection with nginx (with proxy_connect module).
* Establish HTTP proxy tunnel to github.com:443                   -'
> CONNECT github.com:443 HTTP/1.1                                 -.
> Host: github.com:443                                         (1) | curl sends CONNECT request to create tunnel.
> User-Agent: curl/7.43.0                                          |
> Proxy-Connection: Keep-Alive                                    -'
>
< HTTP/1.0 200 Connection Established                             .- nginx replies 200 that tunnel is established.
< Proxy-agent: nginx                                           (2)|  (The client is now being proxied to the remote host. Any data sent
<                                                                 '-  to nginx is now forwarded, unmodified, to the remote host)

* Proxy replied OK to CONNECT request
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256  -.
* Server certificate: github.com                                   |
* Server certificate: DigiCert SHA2 Extended Validation Server CA  | curl sends "https://github.com" request via tunnel,
* Server certificate: DigiCert High Assurance EV Root CA           | proxy_connect module will proxy data to remote host (github.com).
> GET / HTTP/1.1                                                   |
> Host: github.com                                             (3) |
> User-Agent: curl/7.43.0                                          |
> Accept: */*                                                     -'
>
< HTTP/1.1 200 OK                                                 .-
< Date: Fri, 11 Aug 2017 04:13:57 GMT                             |
< Content-Type: text/html; charset=utf-8                          |  Any data received from remote host will be sent to client
< Transfer-Encoding: chunked                                      |  by proxy_connect module.
< Server: GitHub.com                                           (4)|
< Status: 200 OK                                                  |
< Cache-Control: no-cache                                         |
< Vary: X-PJAX                                                    |
...                                                               |
... <other response headers & response body> ...                  |
...                                                               '-
  • 위 테스트에서는 127.0.0.1:3128을 nginx를 forward proxy로 사용해 https://github.com에 접근하였습니다.
  • 먼저 forward proxy를 통해 proxy_connect를 맺어 CONNECT tunnel이 맺어집니다. 
  • 그 후, 실제 요청을 forward proxy에서 중계해서 https://github.com에 보내고 응답을 받아오는 구조입니다.

Reverse Proxy

reverse proxy

  • reverse proxy는 실제 요청을 처리하는 내부 서버가 아닌 reverse proxy로 설정된 주소로 요청을 하고, 해당 proxy 서버가 뒷단에 있는 내부 서버에 다시 요청을 하는 방식으로 진행합니다.
  • 위 그림에서처럼 reverse proxy는 forward proxy와 다르게 클라이언트는 proxy 서버 자체의 URL로 요청합니다.
    • reverse proxy를 사용하면 내부 서버 정보를 클라이언트에 숨길 수 있습니다.

왜 WAS를 앞단에 reverse proxy를 붙여 서비스할까?

  • WAS가 최전방에 두고 클라이언트가 바로 접근하게 서비스할 수도 있지만, 그렇게 되면 WAS에 보안 이슈가 터졌을 경우 DBMS까지 영향을 받을 가능성이 있어 앞단에 reverse proxy를 주로 두고 서비스를 합니다.
    • WAS는 보통 뒷단에 DBMS와 통신하는 구조이기 때문에 내부망에 주로 위치합니다.
  • reverse proxy를 통해 뒷단의 WAS를 클러스터링하면, 가용성을 높일 수 있고, 사용자가 증가하는 상황에 맞게 WEB 또는 WAS를 유연하게 늘릴 수 있습니다.

Reverse Proxy 사용 용도

  • Load Balancing
  • Content Switching/Redirection
  • Authentication
  • Caching

참고 자료

728x90
반응형