Thief of Wealth
article thumbnail

목표

- HTTP 프록시와 웹 게이트웨이를 비교하고 HTTP 프락시가 어떻게 배치되는지 안다.

- 프록시가 실제 네트워크에 어떻게 배치되어 있는지, 그리고 트래픽이 어떻게 프록시 서버로 가게 되는지 안다.

- 브라우저에서 프록시를 사용하려면 어떻게 설정해야하는지 안다.

- HTTP 프록시 요청이 서버 요청과 어떻게 다른지, 프록시가 어떻게 브라우저의 동작을 미묘하게 바꾸는지 안다.

- 일련의 프록시 서버들을 통과하는 메시지의 경로를, 헤더와 TRACE 메서드를 이용하여 기록하는 방법을 안다.

- 프록시에 기반한 HTTP 접근 제어를 안다.

- 어떻게 프록시와 클라이언트와 서버사이에서 각각의 다른 기능과 버전들을 지원하면서 상호작용할 수 있는지 안다.

 

6.1 웹 중개자

웹 프록시 서버는 클라이언트의 입장에서 트랜잭션을 수행하는 중개인.

프록시 없으면 클라이언트는 http 서버와 직접 이야기해야함.

프록시 있으면 http 서버와 이야기하는 대신에 자신의 입장에서 서버와 대화해주는 프록시와 이야기 하게됨

트랜잭션을 완료하는 것은 클라이언트라는것은 동일하지만, 프록시서버가 제공하는 좋은 서비스를 이용하게 됨

HTTP 프록시 서버는 웹 서버이기도하고, 웹 클라이언트이기도함.

프록시는 HTTP 클라이언트의 요청을 받게 되므로 반드시 웹 서버처럼 요청과 커넥션을 적절히 다루고 응답을 돌려줘야함

또한, 프록시는 요청을 서버로 보내기도하므로 HTTP 클라이언트처럼 동작해야함

 

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

프록시 서버는 하나의 클라이언트가 독점적으로 사용할 수 있고 여러 클라이언트가 공유할 수도 있음

하나의 클라이언트만을 위한 프록시를 개인 프록시라고 부르고 여러 클라이언트가 함께 사용하는 프록시가 공용프록시임

 

- 공용 프록시

대부분 프록시는 공용이고 공유된거임

그리고 중앙 집중형 프록시를 관리하는게 더 비용효율이 높고 쉬움.

뭐.. 캐시 프록시 서버와 같은 몇몇 프록시 어플리케이션은 프록시를 이용하는 사용자가 많을수록 유리하니까 공용으로 만든거같음

(왜냐하면 여러 사용자들의 공통된 요청에서 이득을 취할 수 있기 때문)

 

- 개인 프록시

개인 전용 프록시는 그렇게 흔하지는 않지만 클라이언트 컴퓨터에서 직접 실행되는 형태로 꾸준히 사용되고 있음

어떤 브라우저 보조 제품들은 ISP 서비스와 마찬가지로 브라우저의 기능을 확장하거나 성능을 개선하거나 무료 ISP 서비스를 위한 광고를 운영하기 위해서 작은 프록시를 사용자의 컴퓨터에서 직접 실행함

 

 

6.1.2 프록시 대 게이트웨이

엄밀하게 말하면 프록시는 같은 프로토콜을 사용하는 둘 이상의 어플리케이션을 연결하는거고,

게이트웨이는 서로 다른 프로토콜을 사용하는 둘 이상을 연결하는거임

게이트웨이는 클라이언트와 서버가 서로 다른 프로토콜로 말하더라도 서로간의 트랜잭션을 완료할 수 있도록 해주는 프로토콜 변환기처럼 동작.

 

다른 프로토콜로 변환되면 게이트웨이임

 

 

6.2 왜 프록시를 사용하는가?

프록시 서버는 실용적이고 유용한 것이면 무슨 일이든한다.

보안을 개선하고, 성능을 높여주고, 비용을 절약한다.

그리고 프록시 서버는 HTTP 트래픽을 들여다보고 건드릴 수 있기 때문에 부가적인 가치를 주는 여러 유용한 웹 서비스를 구현하기 위해서 트래픽을 감시하고 수정할 수 있다.

 

예를들어서 아동용 컨텐츠 필터 프록시가 있다면, 서버에서 오는 요청을 거부할 수 있다.

 

또는 문서 접근제어자 필터 프록시가 있다면, 회사 문서의 권한에 위배되는 요청을 거부할 수도 있다. 

 

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

- 어떻게 프록시가 네트워크가 배치되는가

- 어떻게 프록시의 연쇄가 계층을 이루는가

 

6.3.1 프록시 서버 배치

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

- 출구 프록시

- 접근 프록시

- 대리 프록시

- 네트워크 교환 프록시

 

6.3.2 프록시 계층

프록시들은 프록시 계층이라고 불리는 연쇄를 구성할 수 있다.

프록시 계층에서 프록시 서버들은 부모와 자식 관계를 가진다.

서버에 가까운 쪽인 인바운드 프록시를 부모라고 부르고

클라이언트에 가까운 쪽인 아웃바운드 프록시를 자식이라고 부른다.

 

 

부하 균형

자식 프록시는 부하를 분산하기 위해서 현재 부모들의 작업량 수준에 근거하여 부모 프록시를 고른다.

 

지리적 인접성에 근거한 라우팅

자식 프록시는 원서버의 지역을 담당하는 부모를 선택할 수도 있다.

 

프로토콜/타입 라우팅

어떤 자식 프록시는 URI에 근거하여 다른 부모나 원 서버로 라우팅할 수 있다.

어떤 특정 종류의 URI를 갖고 있는 요청의 경우에 특별한 프록시 서버로 보내져 특별한 프로토콜로 처리될 수도 있다.

 

유료 서비스 가입자를 위한 라우팅

웹서비스 운영자가 빠른 서비스를 위해 추가금을 지불했다면, 그들의 URI는 대형캐시나 성능개선을 위한 압축 엔진으로 라우팅 될 수 있다.

 

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

클라이언트는 보통 웹 서버와 직접대화하기 때문에, 어떻게 HTTP 트래픽이 프록시로 향하는 깅를 찾아내는지 설명할 필요가 있다.

클라이언트 트래픽이 프록시로 가도록 만드는 방법에는 다음 4가지가 있다.

 

1. 클라이언트를 수정한다.

많은 클라이언트들이 수동 프록시를 지원하는데, 수동 프록시가 활성화되어있다면 클라이언트는 HTTP 요청을 프록시로 보낸다.

 

2. 네트워크를 수정한다.

클라이언트는 알지도 못하고 간섭도 할 수 없는 상태에서 네트워크 인프라를 가로채서 웹 트래픽을 플가시로 가도록 조정하는 몇가지 기법이 있다.

일반적으로 HTTP 트래픽을 지켜보고 가로채서 클라이언트가 모르게 트래픽을 프록시로 보내는 스위칭 장치와 라우팅 장치를 필요로 한다. (인터셉트 프록시)

 

3. DNS 이름공간을 수정한다.

웹 서버 앞에서 위치하는 프록시 서버인 대리 프록시는 웹 서버의 이름과 IP주소를 자신이 직접 사용한다.

그래서 모든 요청은 서버대신에 대리 프록시로 간다.

이는 DNS 이름 테이블을 수동으로 편집하거나 사용할 적절한 프록시나 서버를 계산해주는 특별한 동적 DNS 서버를 이용해서 조정될 수 있다.

 

 

4. 웹 서버를 수정한다.

몇 웹 서버는 HTTP 리다이렉션 명령을 클라이언트에게 돌려줘서 클라이언트 요청을 프록시로 리다이렉트 하도록 설정할 수 있다.

리다이렉트를 받는 즉시 클라이언트는 프록시와의 트랜잭션을 시작한다.

 

6.4 클라이언트 프록시 설정

프록시를 설정하는 여러가지 방법

1. 수동 설정

: 프록시를 사용하겠다고 명시적으로 설정한다.

 

2. 브라우저 기본 설정
: 브라우저 벤더나 배포자는 브라우저를 소비자에게 전달하기 전에 프록시를 미리 설정해놓을 수 있다.

 

3. 프록시 자동 설정 (PAC)

: 자바스크립트 프록시 자동 설정 (PAC) 파일에 대한 URI를 제공할 수 있다.

클라이언트는 프록시를 써야하는지 그렇다면 어떤 프록시 서버를 써야하는지 판단하기 위해서 그 자바스크립트 파일을 가져와서 실행한다.

 

4. WPAD 프록시 발견

대부분의 브라우저는 자동설정 파일을 다운받을 수 있는 "설정 서버"를 자동으로 찾아주는 웹 프록시 자동발견 프로토콜을 제공한다.

 

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

많은 웹 클라이언트가 프록시를 수동으로 설정할 수 있도록 하고 있다.

 

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

수동 프록시 설정은 단순하지만 유연하지 못하다.

왜냐하면 모든 컨텐츠를 위해서 단 하나의 프록시 서버만을 지정할 수 있고, 장애시의 대체 작동에 대한 지원도 없다.

또한, 수동 프록시 설정은 큰 조직에서는 관리 문제를 야기한다.

으으 설정된 브라우저가 매우 많다면 그 모두를 원하는 대로 설정변경을 하는 것은 어렵거나 불가능하다.

 

그래서 PAC(프록시 자동 설정 파일)은 프록시 설정에 대한 보다 동적인 해결책인데,

왜냐하면 그들은 프록시 설정을 그때그때 상황에 맞게 계산해주는 작은 자바스크립트 프로그램이기 때문이다.

이러면 문서에 접근할때마다 자바스크립트 함수가 적절한 프록시 서버를 선택한다.

 

PAC 파일을 사용하려면 자바스크립트 PAC파일의 URI를 브라우저에 설정해야한다.

브라우저는 URI로부터 PAC파일을 가져와서 매 접근마다 적절한 프록시 서버를 계산하기 위해서 자바스크립트 로직을 이용하는데 PAC 파일은 일반적으로 .pac 확장자를 가지며, MIME 타입은 "application/x-ns-proxy-autoconfig"이다.

 

각 PAC 파일은 반드시 URI내에 접근할때 사용할 적절한 프록시 서버를 계산해주는 FindProxyForUrl 라는 함수를 정의해야하고 이 함수의 반환값은 아래와 같다.

 

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

브라우저 설정을 위한 또 다른 매커니즘은 웹 프록시 자동발견 프로토콜이다. (WPAD)

WPAD는 여러 발견 매커니즘들 상승 전략을 이용해서 브라우저에게 알맞은 PAC 파일을 자동으로 찾아주는 알고리즘이다.

 

- PAC URI를 찾기 위해 WPAD를 사용

- 주어진 URI에서 PAC 파일을 가져온다

- 프록시 서버를 알아내기 위해서 PAC 파일을 실행한다

- 알아낸 프록시 서버를 이용해서 요청을 처리한다

 

 

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

 

6.5.1 프록시 요청의 URI는 서버 요청과 어떻게 다르다

웹서버와 웹프록시 메시지의 문법은 서로같지만, 한가지 예외가 있다.

클라이언트가 프록시 대신에 서버로 요청을 보내면 요청의 URI가 달라진다.

 

왜 서버와 프록시는 각각 다른 요청 형식을 가질까?

원래 HTTP 설계에서 클라이언트는 단일 서버와 직접대화했었다.

가상호스팅따위 존재하지 않았고, 프록시에 대한 대비도 없었다.

 

단일 서버는 자신의 호스트명과 포트번호를 알고 있으므로 클라이언트는 불필요한 정보발송을 피하기 위해서 스킴과 호스트와 포트번호가 없는 부분 URI만 보냈다.

 

프록시가 점점 뜨면서, 부분 URI가 문제가 되기 시작했다.

프록시는 목적지 서버와 커넥션을 맺어야 하기 때문에 그 서버의 이름을 알 필요가 있었다. 그리고 프록시 기반 게이트웨이는 FTP 리소스나 혹은 그 외의 스킴과 연결하기 위해서 URI의 스킴을 알 필요가 있었다.

http1.0의 경우에는 프록시 요청의 경우 완전한 URI를 요구하는 것으로 이 문제를 해결했지만 서버 요청의 부분 URI는 여전히 남아있었다.

즉,

- 클라이언트가 프록시를 사용하지 않도록 설정되어 있다면 부분 URI를 보낸다.

- 클라이언트가 프록시를 사용하도록 설정되어있다면 완전한 URI를 보낸다.

 

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

프록시의 스킴/호스트/포트번호 누락 문제는 가상으로 호스팅 되는 웹 서버가 직면한 것과 같은 문제다.

요청하나가 부분 URI로 오면, 가상으로 호스팅되는 웹 서버는 그 요청이 접근하고자 하는 웹 사이트의 호스트 명을 알 필요가 있다.

 

6.5.3 인터셉트 프록시는 부분 URI를 받는다.

클라이언트가 올바른 http 구현했드면 명시적으로 설정된 프록시한테는 완전한 URI를 보냈을 것이다.

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

왜냐하면 몇몇 프록시는 클라이언트에게는 보이지 않을 수 있기 때문이다.

또, 클라이언트가 프록시를 사용하지 않겠다고 해도 대리 프록시나 인터셉트 프록시를 지날 수 있다.

 

그래서 프록시들이 완전한 URI를 보내지 않을 것이다.

 

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

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

명시적인 프록시 요청에서는 => 완전한 URI를 사용하고

아니면 부분 URI를 사용해야하며, 웹 서버 요청의 경우에는 가상 host 헤더를 사용해야한다.

 

규칙은 다음과 같다

- 완전한 URI가 주어졌다면, 프록시는 그것을 사용해야한다.

- 부분 URI가 주어졌고 host 헤더가 있다면 host 헤더를 이용하여 원 서버의 이름과 포트번호를 알아내야한다.

- 부분 URI가 주어졌으나 host 헤더가 없다면 다음의 방법으로 원 서버를 알아내야 한다.

  - 프록시가 원 서버를 대신하는 대리 프록시라면, 프록시에 실제 서버의 주소와 포트번호가 설정되어 있을 수 있다.

  - 이전에 어떤 인터셉트 프록시가 가로챘던 트래픽을 받았고, 그 인터셉트 프록시가 원IP 주소와 포트번호를 사용할 수 있도록 해두었다면 그 IP주소와 포트번호를 사용할 수 있다.

  - 이게 모두 실패했다면 프록시는 원 서버를 알아낼 수 있는 충분한 정보를 갖고 있지 못한거니까 반드시 에러메시지를 반환해야한다.

 

 

6.5.5 전송 중 URI 변경

프록시 서버는 요청 URI 변경에 신경을 써야한다.

무해해 보이는 사소한 URI 변경이라도 다운스트림 서버와 상호운용성 문제를 일으킬 수 있다.

몇몇 프록시는 URI를 다음 홉으로 보내기 전에 표준 형식으로 '정규화'하는 것으로 알려져있다.

URI에서 기본 HTTP 포트를 명시적인 80포트로 변경하는 것이나 잘못 사용한 예약된 글자를 올바르게 escape 하여 교체하는 것과 같은 무해해보이는 변형이라할지라도 상호운용성 문제를 일으킬 수 있다.

 

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

브라우저는 프록시 존재여부에 따라서 요청 URI를 다르게 분석하는데, 

프록시가 없다면 사용자가 타이핑한 URI를 가지고 그에 대응하는 IP주소를 찾는다.

만약 호스트명이 발견되면 그에 대응하는 IP주소들을 연결에 성공할 때까지 시도해본다.

 

근데 호스트가 발견되지 않는다면, 짧은 약어를 타이핑한 것으로보고 자동화된 호스트명의 확장을 제공하고자 다음과 같이 몇가지 시도를 한다.

 

 

6.5.7 프록시 없는 URI 분석

1. 브라우저의 URI창에 Oreilly 입력하면, Oreilly를 호스트명으로 사용하고 기본 스킴을 "http://"로 바꾸고 기본 포트를 "80"으로, 기본 경로를 "/"으로 간주한다.

 

2a. 브라우저는 호스트 Oreilly를 찾아본다.

2b. 실패했다. 호스트를 알수 없음

 

3a. 브라우저는 DNS를 통해서 www.oreilly.com  으로 자동 확장한다.

3b. 브라우저는 DNS를 통해서 호스트 www.oreilly.com 를 찾는다.

3c. 찾아서 IP 주소를 돌려준다.

 

4a. 브라우저는 IP 주소들에 대해서 성공할 때까지 하나씩 접속을 시도한다.

4b. 성공! 커넥션을 맺는다.

 

5a. 브라우저가 HTTP 요청을 보낸다.

5b. 브라우저는 HTTP 응답을 받는다.

 

 

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

브라우저는 명시적인 프록시가 있는 경우 부분 호스트 명을 자동확장하지 않는다.

즉, oreilly를 보내면 www, com 자동확장하여 http://oreilly.com/ 으로 보내는게 아니고 http://oreilly/라고 보낸다.

 

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

호스트 명 분석은 보이지 않는 인터셉트 프록시와 함께일때 약간 달라진다.

=> 클라이언트 입장에서 프록시는 존재하지 않는것이기 때문.

 

 

6.6 메시지 추적

오늘날 웹 요층의 상당수가 프록시를 지나간다.

또한, 성능상의 이유로 대리 캐시 저장고에 컨텐츠를 복제해두는 방식이 점점 더 흔해지고 있다.

프록식 점점 더 흔해지면서 서로 다른 스위치가 라우터를 넘나드는 IP 패킷의 흐름을 추적하는 것 못지않게 프록시를 지나가는 메시지 흐름을 추적하고 문제점을 찾아내는 것도 필요하게되었다.

 

6.6.1 Via 헤더

Via 헤더 필드는 메시지가 지나는 각 중간 노드의 정보를 나열한다.

메시지가 또 다른 노드를 지날 때마다 중간 노드는 Via 목록의 끝에 반드시 추가되어야 한다.

만약에 Via헤더가 아래와 같으면,

첫번째 프록시는 http1.1 프로토콜을 구현했고 proxy-62~~ 라고불리고, 

두번째 프록시는 http1.0 프로토콜을 구현했고 cache.joes~~~ 라고 불린다는 것을 알 수 있다.

이것이 계속 길어진다면, 수신된 프로토콜 값들이 동일한 것들끼리 하나로 합쳐서 덮어써버릴 수 있다.

 

6.6.2 TRACE 메서드

프록시 서버는 메시지가 전달될 때 메시지를 바꿀 수 있다.

프록시 벤더들도 무수히 많아서, http 프록시 네트워크를 통해 hop by hop으로 전달될때마다 메시지의 내용이 어떻게 변하는지 편리하게 관찰할 방법이 필요하다.

 

 

6.7 프록시 인증

프록시는 접근 제어 장치로서 제공될 수 있다.

그러기 위해서 어떤 컨텐츠에 대한 요청을 차단하는 프록시 인증 매커니즘을 정의하고 있다.

 

6.8 프록시 상호운용성

클라이언트/서버/프록시는 http 명세의 여러버전에 대해서 여러 벤더에 의해 만들어진다.

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

 

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

프록시는 이해할 수 없는 헤더필드는 반드시 그대로 전달해야한다.

같은 이름의 헤더필드가 여러개 있는 경우는 상대적인 순서도 반드시 유지해야한다.

 

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

클라이언트는 OPTIONS를 이용해서 서버의 능력을 먼저 알아낼 수 있다.

요청에 성공한다면 OPTIONS 메서드는 서버에서 지원하거나 지정한 리소스에 대해서 가능한 선택적인 기능들을 서술하는 여러 헤더 필드를 포함한 200응답을 반환한다.

 

어떤 메서드가 지원되는지 서술하는 Allow 헤더하나뿐이다. 

 

6.8.3 Allow 헤더

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

 

profile on loading

Loading...