kakasoo

[HTTP] 15. 프락시 본문

프로그래밍/HTTP

[HTTP] 15. 프락시

카카수(kakasoo) 2020. 11. 30. 10:02
반응형

웹 프락시 서버는 중개자다. 클라이언트와 서버 사이에서 중개하는 역할을 한다. 이 장에서는 프락시 기능과 동작을 포함한, HTTP 프락시의 모든 것을 배운다.

  • HTTP 프락시와 웹 게이트웨이의 비교
  • 프락시의 활용법
  • 프락시의 실제 네트워크에서의 배치와 트래픽이 프락시 서버로 가는 과정
  • 브라우저에서의 프락시 설정
  • HTTP 프락시 요청과 서버 요청의 차이, 프락시가 브라우저 동작을 바꾸는 과정
  • 프락시 서버들을 통과하는 메시지의 경로를 Via 헤더와 TRACE 메서드를 통해 기록하는 법
  • 프락시에 기반한 HTTP 접근 제어
  • 프락시가 클라이언트와 서버 사이에서 다른 기능과 버전들을 지원하는 원리

6.1 웹 중개자

프락시는 클라이언트 사이에서 서버와의 트랜잭션을 중개하는 역할을 한다. 프락시가 없으면 클라이언트는 서버와 직접 소통해야 한다.

트랜잭션을 완료하는 것이 클라이언트라는 점은 변하지 않지만, 프락시 서버가 제공하는 서비스를 이용하게 된다.

HTTP 프락시 서버는 서버이자 클라이언트다. 따라서 두 역할을 모두 수행할 수 있어야 한다.

6.1.1 개인 프락시와 공유 프락시

공용 프락시

대부분의 프락시는 공유 프락시이다. 이는 여러 클라이언트가 쓸 수 있다는 뜻이다.

개인 프락시

흔하지 않지만, 하나의 클라이언트를 위해 사용되는 프락시이다.

6.1.2 프락시 대 게이트웨이

엄밀하게 말하면 프락시는 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결하고, 게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상을 연결한다. 게이트웨이는 클라이언트와 서버 사이에서 프로토콜 변환기로 동작하는 셈이다.

6.2 왜 프락시를 사용하는가

프락시 서버는 보안을 개선하고 성능을 높여주며 비용을 절약하는 등 여러 목적을 수행한다. 프락시 서버는 모든 HTTP 트래픽을 들여다보고 건드릴 수 있기 때문에 감시 및 수정의 용도로도 사용한다.

  • 어린이 필터 : 성인 콘텐츠를 차단하는 것도 필터링 목적의 프락시로 해결한다.
  • 문서 접근 제어자 : 서버와 리소스에 대한 단일한 접근 제어 전략을 구현하고 감사 추적을 하기 위해 사용될 수 있다.
  • 보안 방화벽 : 보안을 목적으로 만든 프락시이다.
  • 웹 캐시 : 인기 있는 문서의 로컬 사본을 관리하고 해당 문서에 대한 요청을 빠르게 처리해준다. 원 서버의 캐시를 가진 프락시가, 요청을 도중에 처리해주는 역할을 한다.
  • 대리 프락시 : 이전에, 어떤 프락시들은 웹 서버인 것처럼 위장한다고 했는데, 이는 대리 프락시를 의미한다. 대리 프락시는 요청을 받으면 그 요청이 가리키는 대상을 찾기 위해서, 다른 서버들과 커뮤니케이션을 시작한다. 대리 프락시는 웹 서버의 성능을 개선하기 위해 사용될 수 있다. 따라서 서버 가속기라고도 한다.
  • 콘텐츠 라우터 : 인터넷 트래픽 조건과 콘텐츠의 종류에 따라 요청을 특정 웹서버로 유도한다.
  • 트랜스 코더 : 콘텐츠를 클라이언트에게 전달하기 전에 본문 포맷을 수정한다. 이를 트랜스 코딩이라고 한다. 예컨대 자신을 거쳐 가는 GIF 이미지를 JPG 이미지로 변환하는 것 등을 말한다. 또는 기기 (Ex. 컴퓨터에서 모바일로) 간에 적합한 형태로 파일을 변환하기도 한다.
  • 익명화 프락시 : 개인정보와 익명성 보장을 위해 신원을 특별할 수 있는 특성을 제거한다.

6.3 프락시는 어디에 있는가?

  • 어떻게 프락시가 네트워크에 배치되는가?
  • 어떻게 프락시의 연쇄가 계층을 이루는가?

6.3.1 프락시 서버 배치

어떻게 사용할지에 따라서 프락시는 어디에든 배치될 수 있다.

  • 출구 프락시 : (출구라 하여 오해가 생길 수 있으나) 로컬 네트워크의 출구에서, 요청을 통제한다.
  • 접근(입구) 프락시 : 인터넷 대역폭 비용을 줄이기 위해 캐시 프락시를 사용해 많이 찾는 문서들의 사본을 저장한다.
  • 대리 프락시
  • 네트워크 교환 프락시 : 트래픽 흐름을 감시하기 위해 네트워크 사이의 인터넷 피어링 교환지점에 놓이는 프락시.

출구와 입구라는 말 때문에 많이 헷갈릴 수 있는데, 사실 프락시의 위치가 클라이언트와 서버 사이에 있음을 감안한다면, 결국 출구 입구 모두 위치가 엇비슷한 자리일 것이다.

그럼에도 출구와 입구라는 표현으로 나눈 이유는, 프락시를 기준으로 하여 클라이언트와 서버 사이의 요청을 나눌 수 있기 때문이다.

클라이언트에서 프락시로 가는 것, 즉 출구 쪽에서 요청을 통제한다. 많은 비용이 나오지 않게 통제한다는 예시를 생각하면 이해가 빠를 것이다.

이번에는 프락시에서 서버로 가는 것, 이 역시도 결국 출구 프락시와 위치는 같겠지만, 이 경우를 입구 프락시라고 하며 캐시 프락시를 생각하면 된다.

6.3.2 프락시 계층

여러 프락시들이 연쇄적으로 있는 계층. 프락시 서버들이 부모와 자식의 관계를 지닌다. 인바운드 프락시를 부모, 아웃바운드 프락시를 자식이라고 한다.

  • 프락시 계층 콘텐츠 라우팅
    • 동적 부모 선택 : 프락시 계층의 프락시들은 반드시 정적인 것이 아니다. 필요에 따라 자유롭게 이동하며, 서버나 클라이언트로 바로 접근할 수도 있다.
      • 부하 균형
      • 지리적 인접성에 근거한 라우팅
      • 프로토콜/타입 라우팅
      • 유료 서비스 가입자를 위한 라우팅

6.3.3 어떻게 프락시가 트래픽을 처리하는가

HTTP 트래픽이 프락시로 향하는 길을 찾아내는지 설명할 필요가 있다. 클라이언트 트래픽이 프락시로 가도록 만드는 방법은 4가지가 있다.

  1. 클라이언트를 수정한다.
    • 브라우저를 포함한 많은 웹 클라이언트들은 수동 및 자동 프락시 설정을 지원한다.
    • HTTP 요청을 의도적으로 원 서버가 아닌 프락시로 가게 한다.
  2. 네트워크를 수정한다.
    • 클라이언트가 인지하지 못하는 상태에서, 네트워크 인프라를 가로채서 조정한다.
    • 인터셉트 프락시라고 부른다.
  3. DNS 이름공간을 수정한다.
  4. 웹 서버를 수정한다.

클라이언트를 수정하는 것은, 클라이언트로부터 프락시로 가게끔, 에이전트가 이미 설정되어 있는 경우를 의미한다. 다이렉트 연결인 셈이다. (내 임의의 표현이다.)

또는 라우터를 통해 가로채거나, 대리 프락시를 거치거나, 서버에 도착한 다음에 프락시로 가는 등 여러 가지 방법이 있다.

6.4 클라이언트 프락시 설정

  • 수동 설정 : 프락시를 사용하겠다고 명시적으로 설정한다.
  • 브라우저 기본 설정 : 배포자는 브라우저를 소비자에게 전달하기 전에 프락시를 미리 설정할 수 있다.
  • 프락시 자동 설정 : 자바스크립트 프락시 자동설정 (PAC) 파일에 대한 URI를 제공할 수 있다. 클라이언트는 프락시의 필요성과, 어떤 프락시를 선택할지에 대해 판단하기 위해 해당 자바스크립트 파일을 실행한다.
  • WPAD 프락시 발견 : 대부분 브라우저는 자동설정 파일을 다운받을 수 있는, 프락시 자동발견 프로토콜을 제공한다.

6.4.1 클라이언트 프락시 설정 : 수동

생략한다.

6.4.2 클라이언트 프락시 설정 : PAC 파일

수동 프락시 설정은 유연하지 못하다. PAC 파일은 자바스크립트를 이용한 동적 설정이기 때문에 더 자유롭다.

6.4.3 클라이언트 프락시 설정 : WPAD

WPAD는 여러 발견 메커니즘들의 상승 전략으로 브라우저에게 알맞는 PAC를 찾아준다.

  • PAC URI를 찾기 위해 WPAD를 사용한다.
  • 주어진 URI에서 PAC 파일을 가져온다.
  • 프락시 서버를 알아내기 위해 PAC 파일을 실행한다.
  • 알아낸 프락시 서버를 이용해서 요청을 처리한다.

6.5 프락시 요청의 미묘한 특징들

  • 프락시 요청의 URI는 서버 요청과 어떻게 다른가
  • 인터셉트 프락시와 리버스 프락시는 어떻게 서버 호스트 정보를 알아내기 어렵게 만드는가.
  • URI 수정 규칙
  • 프락시는 브라우저의 URI 자동완성이나 호스트 명 확장 기능에 어떤 영향을 주는가?

6.5.1 프락시 URI는 서버 URI와 다르다

서버는 부분 URI이 아니라, 프락시를 위해 전체 URI을 다룰 필요가 있다는 내용.

6.5.2 가상 호스팅에서 일어나는 같은 문제

명시적인 프락시는 요청 메시지가 완전한 URI 를 갖도록 함으로써 문제를 해결. 가상으로 호스팅 되는 웹 서버는 호스트와 포트에 대한 정보가 담겨 있는 Host 헤더를 요구한다.

6.5.3인터셉트 프락시는 부분 URL을 받는다

클라이언트는 자신이 프락시와 대화하고 있음을 항상 알고있는 것은 아니다.

몇몇 프락시는 클라이언트에게 보이지 않기 때문에 클라이언트가 프락시를 사용한다고 설정되어 있지 않더라도 여전히 대리 혹은 인터셉트 프락시를 지날 수 있다.

클라이언트는 자신이 웹 서버와 대화하고 있다고 생각하고 완전한 URI를 보내지 않을 수도 있다.

6.5.4 프락시는 프락시 요청과 서버 요청을 모두 다룰 수 있다

트래픽이 프락시 서버로 리다이렉트 될 수 있는 여러 가지 방법이 존재하기 때문에, 다목적 프락시 서버는 요청 메시지의 완전한 URI부분 URI을 모두 지원해야 합니다

6.5.5 전송 중 URI 변경

요청 URI의 변경에 매우 신경을 써야한다. 사소한 URI 변경이라도 다운스트림 서버와 상호운용성 문제를 일으킬 수 있다.

프락시들은 절대로, 경찰처럼 행동해서는 안 된다. 있는 그대로 받아서 그대로 돌려주는 것을 원칙으로 한다. 중간에 수정을 해서는 안 된다.

6.5.6 URI 클라이언트 자동 확장과 호스트 명 분석 (Hostname Resolution)

브라우저는 프락시의 존재 여부 에 따라 요청 URI를 다르게 분석한다. 프락시가 없다면 사용자가 타이핑한 URI를 가지고 그에 대응하는 IP 주소를 찾는다.

6.5.7 프락시 없는 URI 분석 (URI Resolution)

6.5.8 명시적인 프락시를 사용할 때의 URI 분석

6.5.9 인터셉트 프락시를 이용한 URI 분석

6.6. 메세지 추적

오늘 날에는 웹 요청이 둘 이상의 프락시를 지나서 도착하는 경우가 드물지 않다. 예를 들어 많은 회사들이 보안과 비용 절감을 위해 캐시 프락시를 사용한다.

캐시 프락시는, 요청의 결과 값에 관한 것을 미리 캐시해두어, 해당하는 정보가 있을 경우 서버에 요청을 보내지 않고 프락시가 임의로 처리하는 것이다.

그런데 이런 캐시 프락시, 각자 다른 벤더(재화와 용역을 제공하는 회사)들에 의해 개발되고 점점 흔해지면서 서로 다른 스위치, 라우터를 넘나드는 것도 흔한 일이 되었다.

따라서 프락시를 넘나드는 메시지의 흐름을 추적하고 문제점을 찾아내는 것도 필요한 일이 되었다.

6.6.1 Via 헤더

가장 간단한 방법은 메세지의 헤더에 계속해서 경로를 저장하는 것이다. Via 헤더는 자신이 거친 노드를 항상 목록 끝에 추가한다. Via 헤더에 값이 2개면 2개를 거쳤다는 뜻이다.

여기서 이 2개는, 클라이언트와 서버를 제하고 중간에 거친 프락시들을 의미한다. 이렇게 관측된 결과는 메시지 발송자들의 프로토콜 능력을 알아보기 위해 사용된다.

서버 : 클라이언트에게 정보를 주려면 프로토콜을 낮은 버전으로 써야 겠군.

또한 프락시는 네트워크 라우팅 루프를 탐지하기 위해 Via 헤더를 사용할 수 있다. 라우팅 루프란 동일한 경로를 반복적으로 순회하는 것을 말한다.

Via 문법

Via 헤더 필드는 쉼표로 구분된 경유지(waypoint)의 목록이다. 경유지는 프락시 서버나 게이트웨이 홉을 나타내며, 프로토콜과 주소의 정보를 가진다.

Via: 1.1 proxy-62.irenes-isp.net, 1.0 cache.joes-hardware.com Via는 "Via" ":" (waypoint) [", " (waypoint) ...]의 형태이며, waypoint는 다시 ( received-protocol received-by [ comment ] )의 형태를 지닌다. received-protocol = [ protoco-name "/"] protocol-version received-by = ( host [ ":" port ] ) | pseudonym

각 Via waypoint는 프로토콜 이름 (선택, 기본 값은 HTTP), 프로토콜 버전 (필수), 노드 이름(필수), 코멘트(선택)의 최대 4개의 구성 요소를 담을 수 있다.

프로토콜 이름

만약 프로토콜이 HTTP 라면 생략할 수 있다. 프로토콜 이름은 버전 앞에 "/"로 구분되어 붙는다. 비 HTTP 프로토콜은 게이트웨이가 다른 프로토콜을 위해 HTTP 요청에 접속할 때 발생할 수도 있다.

프로토콜 버전

수신한 메시지의 버전. 버전의 포맷은 프로토콜에 달려 있다. 버전은 Via 필드에 포함되므로 애플리케이션들은 자신 이전의 모든 중개자들이 어떤 버전을 다룰 수 있는지 알 수 있다.

노드 이름

중개자의 호스트와 포트 번호. 만약 포트 번호가 포함되지 않는다면 프로토콜의 기본 포트라고 간주할 수 있다.

몇몇 조직은 정보 보호를 이유로 진짜 호스트 명을 밝히고 싶지 않을 수도 있는데, 그러한 경우에 가명으로 대체할 수 있다.

노드 코멘트

중개자 노드를 서술하는 선택적인 코멘트. 벤더나 버전 정보를 여기에 포함시키는 것은 흔한 일이며, 몇몇 프락시는 장치에서 일어난 이벤트의 진단 정보를 포함시키기도 한다.

Via 요청과 응답 경로

요청 메시지와 응답 메시지 모두 프락시를 지나므로 둘 모두 Via 헤더를 가진다. 요청과 응답은 보통 같은 TCP 커넥션을 오가는데, 응답 메시지는 요청과 같은 경로로 돌아간다.

만약 요청 메시지가 A,B,C의 프락시를 거쳤다면 응답은 그 반대로, C,B,A의 경로를 지난다. 응답의 Via 헤더는 즉, 항상 요청의 반대라고 할 수 있다.

Via와 게이트웨이

몇몇 프락시는 서버에게 비 HTTP 프로토콜을 사용할 수 있도록 하는 게이트웨이 기능을 제공한다. Via 헤더는 이러한 프로토콜 변환을 기록한다.

따라서 HTTP 애플리케이션은 프락시 연쇄에서 프로토콜 능력과 변환이 있는지 알 수 있다.

Server 헤더와 Via 헤더

Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려준다. 예를 들면 다음과 같다.

Server: Apache/1.3.14 (Unix) PHP/4.0.4 Server: Netscape-Enterprise/4.1 Server: Microsoft-IIS/5.0

Via가 개인정보 보호와 보안에 미치는 영향

Via 문자열 안에 정확한 호스트 명이 들어가지를 원하지 않는 경우가 있다. 명시적으로 Via를 실행하지 않는 경우에는, 절대 동작해서는 안된다.

프락시 서버가 네트워크 방화벽의 일부인 경우에, 프락시는 방화벽 뒤에 있는 호스트의 이름과 포트를 전달할 수도 있다. 이는 악의적인 이용을 허용한다.

만약 Via 노드의 이름 전달이 가능하지 않다면, 보안 경계선의 일부분인 프락시는, 호스트 명을 적절한 가명으로 교체해야 한다. 또한 실제 이름이 아니더라도 Via는 그걸 옮긴다.

6.6.2 TRACE 메서드

프락시 서버는 메시지가 전달될 때 메시지를 바꿀 수 있다. 헤더가 추가되거나 변경되거나 삭제될 수도 있으며 본문이 다른 형식으로 변환될 수도 있다.

프락시가 복잡해지고 더 많은 벤더가 프락시 제품을 배치하면서, 상호 운용성 문제가 증가한다. 프락시 네트워크를 더 쉽게 진단하기 위해 우리는 홉에서 홉으로 전달될 때마다 메시지의 내용이 어떻게 변하는지 더 쉽게 관찰할 방법이 필요하다.

HTTP/1.1의 TRACE 메서드는 요청 메시지를 프락시를 연쇄를 따라가면서 어떤 프락시를 지나가고 메시지가 어떻게 수정되는지를 추적할 수 있게 해준다.

TRACE 요청이 목적지 서버에 도착했을 때 서버는 전체 요청 메시지를 HTTP 응답 메시지의 본문에 포함시켜 송신자에게 그대로 돌려준다.

Max-Forwards

일반적으로 TRACE 메시지는 중간에 프락시들이 몇 개나 있든 상관하지 않고 목적지 서버로의 모든 경로를 여행한다. 이 때 경로의 수를 제한하는 것이 Max-Forwards 이다.

이는 프락시가 루프에 빠지는지를 테스트해보는 데에 용이하다. 만약 TRACE 메서드가 서버에 도착하기 전에 경로 수가 한계에 도달하면 원하는 지점이 아니라고 하더라도

HTTP 메시지는 클라이언트에게 돌아간다.

6.7 프락시 인증

프락시는 접근 제어 장치로도 사용될 수 있다. HTTP는 사용자가 유효한 접근 권한을 프락시에게 제출하지 않는 한 콘텐츠에 대한 요청을 차단하는 프락시 인증을 정의하고 있다.

  • 제한된 콘텐츠에 대한 요청이 들어왔을 때 407 (Proxy Authorization Required) 상태코드와, 어떻게 권한을 제출할 수 있는지 설명하는 Proxy-Authenticate 헤더를 반환한다.
  • 클라이언트는 407 응답을 받게 되면, 요구되는 자격을 수집해야 한다.
  • 자격을 수집하면, 클라이언트는 해당 자격을 다시 Proxy-Authorization에 담아서 다시 요청을 보낸다.
  • 자격이 유효하면 통과, 유효하지 않으면 다시 407 응답을 보낸다.

프락시 인증은, 인증에 참여하는 프락시가 프락시 연쇄 상에 여러 개 있을 때에는 잘 동작하지 않는다.

6.8 프락시 상호 운용성

프락시 서버는 서로 다른 프로토콜로 구현됐을 수도 있고, 골치 아프게 이상한 동작을 할 수 있는, 클라이언트와 서버 사이를 중개해야 한다.

6.8.1 지원하지 않는 헤더와 메서드 다루기

프락시 서버는 넘어오는 헤더 필드들을 모두 이해하지 못할 수도 있다. 몇몇 헤더는 프락시 자신보다도 더 최신 버전일 수도 있다. 또 커스텀 헤더일 수도 있다.

프락시는 자신이 이해할 수 없다고 하더라도 모든 헤더를 그대로 전달해야 하며, 같은 이름의 헤더 필드가 여러 개인 경우, 상대적인 순서도 반드시 유지해야 한다.

6.8.2 OPTIONS: 어떤 기능을 지원하는지 알아보기

HTTP OPTIONS 메서드는 서버나 웹 서버의 특정 리소스가 어떤 기능을 지원하는지, 클라이언트가 알아볼 수 있게 해준다.

서로 다른 기능 수준의 서버와 프락시가 더 쉽게 상호작용할 수 있도록, 클라이언트는 OPTIONS를 이용해 서버의 능력을 먼저 알아낼 수 있다.

만약 OPTIONS 요청의 URI에 별표(*)이라면, 요청은 서버 전체의 능력에 대해 묻는 것이 된다.

만약 URI가 실제 리소스라면, OPTIONS는 특정 리소스에 대해 가능한 기능들을 묻는 것이 된다.

6.8.3 Allow 헤더

Allow 엔터티 헤더 필드는, 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드들이나 서버가 지원하는 모든 메서드를 열거한다.

allow : get, post, delete

반응형