[HTTP 완벽 가이드] 06. 프락시

thumbnail
Photo by Manja Vitolic on Unsplash

프락시는 서버와 클라이언트 사이에서 중간에서 최적화 할 수 있는 모든 것을 한다.

키워드

프락시, 게이트웨이, 클라이언트 프락시 설정, Via 필드, TRACE 메서드, OPTION 메서드, Allow 헤더

메모 및 핵심 요점

  • 웹 프락시 서버 : 클라이언트 입장에서 트랜잭션을 수행하는 중계인, 웹 프락시가 있다면 클라이언트는 HTTP 서버와 직접 대화하는게 아니라 웹 프락시 서버와 대화하게 됨.
  • HTTP 프락시 서버 : 웹 서버와 웹 클라이언트의 중간에 위치함 ⇒ 클라이언트이면서 서버의 역할을 한다.
  • 캐시 프락시 서버와 같은 몇몇 프락시 애플리케이션은 사용자가 많을수록 유리한데, 이는 공통된 요청에서 이득을 취할 수 있기 때문이다. (🌧️ 공통된 요청을 통하여 이득을 취하는 형태는 컴퓨터에서 cache 전략을 사용하는 것과 비슷한 느낌이다. 이러한 요청들이 일종의 locality를 가진 것 같기도 하고..)
  • 프락시와 게이트웨이의 차이점 : 프락시는 같은 프로토콜에서 움직이는 둘 이상의 애플리케이션을 연결하고 게이트웨이는 다른 프로토콜에서 움직이는 둘 이상의 애플리케이션을 연결한다. 즉 둘 다 일종의 중계자 역할을 하지만, 게이트웨이의 경우 서로 다른 프로토콜간의 트랜잭션을 수행할 수 있는 변환기역할을 한다.
  • 프락시 서버는 그를 거쳐가는 모든 HTTP 트래픽을 들여다보고 건드릴 수 있다.
  • 프락시를 사용하는 다양한 예제 : 필터, 문서 접근 제어자, 방화벽, 캐시, 리버스 프락시, 콘텐츠 라우터, 트랜스코더, 익명화 등 ⇒ 🌧️ 어쨌든 서버와 클라이언트 중간에서 그들의 트랜잭션을 위한 유용한 역할들을 프락시 단에서 수행하도록 구현한다.
  • 클라이언트 트래픽을 프락시로 가게 하는 방법 : 클라이언트 수정, 네트워크 수정 (인터셉트 프락시), DNS 이름 공간 수정, 웹 서버 수정 (HTTP 리다이렉션 명령 (응답코드 305) 사용)
  • 클라이언트가 웹 서버에 요청을 보낼 때는 요청줄에 부분 URI를 사용하지만, 프록시에 요청을 보낼 때는 완전한 URI 를 사용한다. 🌧️ 이는 프락시가 서버와 클라이언트 중간에 끼어있기 때문인데, 클라이언트에서 보낸 요청을 프락시가 서버로 전달하기 위해서는 프락시는 서버의 이름을 알 필요가 있다.
  • 🌧️ Next.js 의 SSG 처럼 CDN을 이용한 캐싱 방식을 사용할 때, 프록시 서버를 사용한다고 말할 수 있다. 사용자와 (물리적으로) 가까운 위치에 있는 캐시 프록시를 두고 그 프록시에서 콘텐츠를 받아옴으로써 빠른 성능을 이용할 수 있다. (일종의 edge computing이라고 할 수도 있을 것 같다)
  • 프락시를 넘나드는 메시지를 추적하는 방법 : Via 필드, TRACE 메서드
  • TRACE와 OPTION과 같이 프락시를 넘나드는 메서드를 사용할 때, 거치는 프락시 홉의 갯수를 지정하기 위하여 Max-Forwards 헤더를 사용할 수 있다. 이 값은 홉을 하나씩 거쳐갈 때마다 하나씩 줄어들며, 모든 프락시나 게이트웨이는 Max-Fowards 를 지원해야 한다.
  • 프락시 서버가 어떤 메시지를 중계할 때, 이해할 수 없는 헤더를 만나거나 친숙하지 않은 메서드를 만나는 경우 가능한 그대로 전달하여야 한다.
  • 서버가 어떤 기능을 지원하는지 알기 위하여 HTTP OPTION 메서드를 사용할 수 있다.
  • Allow 헤더는 서버에 의해 어떤 메서드가 지원되는 지를 서술한다.

스터디에서 배운 내용

  • (출처) 리액트 CRA를 개발환경(dev)에서 실행하게 되면 CORS가 허용되는 이유는, CRA를 통하여 webpack 설정을 하게 되고, 이 webpack이 프락시 서버를 만들고 브라우저 설정을 통하여 (브라우저의 프락시 설정을 사용하여 HTTP 요청을 바로 프락시로 보낸다) 프록시에 요청을 보내도록 한다.
module.exports = {
  devServer: {
    proxy: {},
  },
}

cra_proxy

🌧️ 본인이 직접 겪은 일은 아니지만, Next.js 를 사용할 때, 로컬 환경에서 CORS 문제가 생겨서 next.config.jsrewrites 설정으로 해결하신 분이 계셨다. 해당 내용은 공식문서에서 확인할 수 있다.

Rewrites act as a URL proxy and mask the destination path, making it appear the user hasn’t changed their location on the site. In contrast, redirects will reroute to a new page and show the URL changes.

아마 위의 CRA에서 CORS를 회피하는 방법가 일맥상통한 내용인 것 같다. 조만간 쿠키를 통해서 인증 로직을 구현할 일이 한번 더 생기는데, 이번에는 기존의 방법이 아니라 응답헤더를 사용하는 방식이 필요할 것 같은데 해당 경우에서 이 내용을 사용 할 수 있을 것 같다.

인용

엄밀하게 말하면, 프락시는 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결하고, 게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상을 연결한다. 게이트웨이는 클라이언트와 서버가 서로 다른 프로토콜로 말하더라도 서로 다른 트랜잭션을 완료할 수 있도록 해주는 프로토콜 변환기 처럼 동작한다. (149p)

브라우저와 서버는 다른 버전의 HTTP를 구현하기 때문에, 프락시는 때때로 약간의 프로토콜 변환을 하기도 한다. 그리고 상용 프락시 서버는 SSL 보안 프로토콜, SOCKS 방화벽, FTP 접근, 그리고 웹 기반 애플리케이션을 지원하기 위해 게이트웨이 기능을 구현한다. (150p)

프락시와 서버 요청 모두에 대해 HTTP/1.1은 현재 서버들이 완전한 URI를 다룰 것을 요구한다. 그러나 현실에서는 배치되어 있는 서버들 중 다수가 여전히 부분 URI만을 받아들인다. (165p)

클라이언트는 자신이 프락시와 대화하고 있음을 항상 알고 있는 것은 아니다, 왜냐하면 몇몇 프락시는 클라이언트에게는 보이지 않을 수 있기 때문이다. 비록 클라이언트가 프락시를 사용한다고 설정되어 있지 않더라도, 클라이언트의 트래픽은 여전히 대리 프락시나 인터셉트 프락시를 지날 수 있다. 두 가지 경우 모두, 클라이언트는 자신이 웹 서버와 대화하고 있다고 생각하고 완전한 URI를 보내지 않을 것이다. (166-167p)

Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려준다. (중략) Server 헤더는 원 서버를 위해 존재한다. (176p)

HTTP/1.1의 TRACE 메서드는 요청 메시지를 프락시의 연쇄를 따라가면서 어떤 프락시를 지나가고 어떻게 각 프락시가 요청 메시지를 수정하는지 관찰/추적 할 수 있도록 해준다. TRACE는 프락시 흐름을 디버깅하는데 매우 유용하다. (177p)

참고자료

[Infra] 리버스 프록시(reverse proxy) 서버 개념

[Nginx] 리버스 프록시(Reverse Proxy) 개념 및 사용법


Written by@AllSilver
철학적인 개발자를 꿈꿉니다.

GitHub