웹 프락시 서버는 클라이언트와 서버 사이에 위치하여 그들 사이의 HTTP 메시지를 정리하는 중개인처럼 동작한다.
웹 중계자
웹 프락시 서버는 클라이언트 입장에서 트랜잭션을 수행하는 중개인이다.
- 프락시가 없을 때 ➡️ 프락시 서버와 통신
- 프락시가 있을 때 ➡️ HTTP 서버와 직접 통신
HTTP 프락시 서버는 웹 서버인 동시에 클라이언트이다. HTTP 클라이언트의 요청을 받고, 요청을 서버로 보내기도 하기 때문이다.
1) 개인 프락시와 공유 프락시
프락시 서버는 하나의 클라이언트가 독점적으로 사용할 수도 있고, 여러 클라이언트가 공유할 수도 있다.
2) 프락시 대 게이트웨이
- 프락시: 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결
- 게이트웨이: 서로 다른 프로토콜을 사용하는 둘 이상을 연결
실질적으로 프락시와 게이트웨이의 차이점은 모호하다. 상용 프락시는 다른 버전의 HTTP를 구현하기 위해 프로토콜 변환을 하거나 SSL 보안 프로토콜, SOCKS 방화벽, FTP 접근, 웹 기반 애플리케이션을 지원하기 위해 게이트웨이 기능을 구현한다.
왜 프락시를 사용하는가?
1) 프락시 서버가 하는 일
- 보안 개선
- 성능 향상
- 비용 절약
- 트래픽 감시 및 수정
2) 사용 예시
1. 어린이 필터
2. 문서 접근 제어자
많은 웹 서버들과 웹 리소스에 대한 단일한 접근 제어 전략을 구현하고 감사 추적하기 위해 사용될 수 있다.
각기 다른 조직에서 관리되는 다양한 종류의 수많은 웹 서버들에 대한 접근 제어를 수시로 갱신할 필요 없이, 중앙 프락시 서버에서 접근 제어를 설정할 수 있다.
- 클라이언트 1에게 제약 없이 서버의 뉴스 페이지에 접근할 수 있도록 허가
- 클라이언트 2에게 제약 없이 인터넷 콘텐츠에 접근할 수 있는 권한 제공
- 클라이언트 3이 서버 B에 접근하기 전에 먼저 비밀번호 요구
3. 보안 방화벽
프락시 서버는 조직 내에 들어오거나 나가는 애플리케이션 프로토콜의 흐름을 네트워크 한 지점에서 통제한다.
4. 웹 캐시
프락시 캐시는 인기 있는 문서의 로컬 사본을 관리하고 해당 문서에 대한 요청이 오면 빠르게 제공
5. 대리(리버스) 프락시(Surrogate)
어떤 프락시는 웹 서버인 것처럼 위장한다. 대리 프락시들은 웹 서버 요청을 받지만 웹 서버와 달리 요청 받은 콘텐츠의 위치를 찾아내기 위해 다른 서버와 커뮤니케이션을 시작한다.
대리 프락시는 공용 콘텐츠에 대한 느린 웹 서버의 성능을 개선하기 위해 사용될 수 있다. 이런 대리 프락시는 서버 가속기라고 불린다.
6. 콘텐츠 라우터
프락시 서버는 인터넷 트래픽 조건과 콘텐츠의 종류에 따라 요청을 특정 웹 서버로 유도하는 콘텐츠 라우터로 동작할 수 있다.
콘텐츠 라우터는 사용자들에게 제공할 여러 서비스를 구현하는데 사용할 수 있다.
예시) 사용자, 서비스 제공자가 더 높은 성능을 위해 돈을 지불한 경우,요청을 가까운 복제 캐시로 전달
7. 트랜스코더
프락시 서버는 콘텐츠를 클라이언트에게 전달하기 전에 본문 포맷을 수정(트랜스코딩)할 수 있다.
예시) 다국어 지원(한국어 텍스트를 스페인어 텍스트로 변환)
8. 익명화 프락시
익명화 프락시는 HTTP 메시지에서 신원을 식별할 수 있는 특성들을 적극적으로 제거함으로써 개인 정보 보호와 익명성 보장에 기여한다.
신원을 식별할 수 있는 특성들
클라이언트 IP 주소, From 헤더, Referer 헤더, 쿠키, URI 세션 아이디 등
프락시는 어디에 있는가?
1) 프락시 서버 배치
프락시는 다양한 곳에 배치할 수 있다.
a. 출구(Egress) 프락시
로컬 네트워크와 더 큰 인터넷 사이를 오가는 트래픽을 제어하기 위해 프락시를 로컬 네트워크의 출구에 넣을 수 있다.
출구 프락시는 클라이언트 측에 배치된다.
클라이언트가 내부 네트워크에서 외부 서버로 요청을 보낼 때, 이 요청이 먼저 출구 프락시를 거쳐서 외부로 나가는 방식이다.
역할
- 클라이언트 보호: 클라이언트가 직접적으로 서버에 접근하지 않도록 하여 보안을 강화한다.
- 웹 필터링: 특정 웹사이트나 콘텐츠에 대한 접근을 제한하는 데 사용된다.
- 익명화: 사용자가 웹 서버에 직접 접속하는 것이 아니라 프락시를 통해 접속하므로, 클라이언트의 IP 주소를 숨길 수 있다.
사용 예시
- 회사 외부의 해커들을 막는 방화벽 제공
- 인터넷 트래픽 성능을 개선하기 위해
- 초등학생들이 부적절한 콘텐츠를 브라우징하는 것을 막기 위해
b. 접근(입구) 프락시
고객으로부터 모든 요청을 종합적으로 처리하기 위해 프락시는 ISP 접근 지점에 위치시키기도 한다. ISP는 사용자의 다운로드 속도를 개선하고 인터넷 대역폭 비용을 줄이기 위해 캐시 프락시를 사용해 많이 사용하는 문서 사본을 저장한다.
접근 프락시는 서버 측에 배치된다.
외부 클라이언트가 서버에 접근하려고 할 때, 클라이언트는 먼저 접근 프락시를 거치고, 이 프락시가 실제 서버로 요청을 전달하는 방식이다.
역할
- 로드 밸런싱: 여러 서버로 트래픽을 분산시키는 역할을 한다. 클라이언트는 단일 접속점(프락시)을 통해 여러 서버로 접속하게 된다.
- 캐싱: 서버의 콘텐츠를 캐싱하여 동일한 요청에 대해 빠른 응답을 제공한다.
- 보안 강화: 실제 서버의 IP를 숨기고, 보안적인 제어를 위해 클라이언트가 직접 서버에 접근하지 못하도록 한다.
사용 예시
- 대형 웹 서비스에서 여러 서버로의 요청을 분산시키거나, 서버의 내용을 캐싱해 클라이언트 응답 속도를 높이는 경우
- DDoS 공격을 방어하기 위해 외부 클라이언트가 실제 서버에 직접 접근하지 않도록 할 때
c. 대리 프락시
대리 프락시는 클라이언트와 서버 사이(웹 서버 앞)에 배치된다. 웹 서버의 바로 앞에 위치하여 웹 서버로 향하는 모든 요청을 처리하고 필요할 때만 웹 서버에게 자원을 요청할 수 있다.
클라이언트와 서버는 프락시를 통과한다는 사실을 인식하지 못하며, 클라이언트의 요청이 프락시를 거쳐 서버에 전달된다.
역할
- 트래픽 모니터링: 클라이언트의 요청을 가로채거나 모니터링하여 특정 정책을 적용하거나 기록할 수 있다.
- 캐싱: 프락시가 요청과 응답을 캐싱하여 동일한 요청에 대해 빠른 응답을 제공한다
사용 예시
- 학교나 도서관에서 인터넷 사용을 모니터링하고, 특정 사이트에 대한 접근을 필터링할 때
- 인터넷 서비스 제공자가 사용자 트래픽을 모니터링하거나 최적화할 때
d. 네트워크 교환 프락시
네트워크 교환 프락시는 네트워크 경계나 네트워크 교환 지점(인터넷 교환소, IX)에 배치됩니다.
이 지점에서 다른 네트워크 간의 데이터 교환이 이루어집니다.
역할
- 네트워크 간 트래픽 중계: 여러 ISP 또는 네트워크 간의 트래픽을 효율적으로 중계하고, 네트워크 혼잡을 줄입니다.
- 트래픽 최적화: 대량의 트래픽을 처리할 때, 트래픽을 효율적으로 관리하고 제어합니다.
- 보안 강화: 네트워크 경계에서 트래픽을 필터링하고, 악성 트래픽을 차단하는 역할도 수행할 수 있습니다.
사용 예시
- 인터넷 서비스 제공자 간 트래픽 교환을 최적화하거나, 네트워크 상의 보안 정책을 강화하기 위해 네트워크 교환소에서 사용
- 대규모 데이터 센터에서 외부 트래픽을 분배하거나 관리할 때.
2) 프락시 계층
프락시 계층에서, 메시지는 최종적으로 원 서버에 도착할 때까지 여러 프락시를 거쳐 이동한다.
프락시 계층에서 프락시 서버들은 서로 부모와 자식의 관계를 갖는다.
서버에 가까운 쪽 프락시(인바운드)는 부모라고 부르고, 클라어언트에 가까운 쪽 프락시(아웃바운드)는 자식이라고 부른다.
프락시 서버는 여러 판단 근거에 의해 메시지를 다양하고 유동적인 프락시 서버와 원 서버에게 보낼 수 있다.
즉, 프락시 계층은 동적으며 매 요청마다 바뀔 수 있다.
동적 부모 선택 요소
- 부하 균형
- 지리적 인접성에 근거한 라우팅
- 프로토콜/타입 라우팅
- 유료 서비스 가입자를 위한 라우팅
3) 어떻게 프락시가 트래픽을 처리하는가
클라이언트 트래픽이 프락시로 가도록 만드는 방법
클라이언트 수정
브라우저를 포함한 웹 클라이언트들은 수동/자동 프락시 설정을 지원한다.
프락시 사용 설정 시, 클라이언트는 HTTP 요청을 원 서버가 아닌 프락시로 보낸다.
네트워크 수정
클라이언트는 모른 채로, 네트워크 인프라를 가로채서 웹 트래픽을 프락시로 가도록 조정하는 방법이며, 트래픽을 프락시로 보내는 스위칭 장치와 라우팅 장치를 필요로 한다. (인터셉트 프락시라고 부른다)
DNS 이름 공간 수정
웹 서버 앞에 위치하는 프락시 서버인 대리 프락시는 웹 서버의 이름과 IP 주소를 자신이 직접 사용한다. 그래서 모든 요청은 서버 대신 대리 프락시로 간다.
웹 서버 수정
몇몇 웹 서버는 HTTP 리다이렉션 명령(상태 코드305)을 클라이언트에게 돌려줌으로써 클라이언트 요청을 프락시로 리다이렉트 하도록 설정할 수 있으며, 클라이언트는 리다이렉트를 받은 즉시 프락시와의 트랜잭션을 시작한다.
클라이언트 프락시 설정
모든 현대적인 브라우저는 프락시를 사용할 수 있도록 설정할 수 있다.
1) 수동 프락시 설정
수동 클라이언트 프락시 설정은 사용자가 클라이언트(예: 웹 브라우저, 운영 체제)의 네트워크 설정에서 프락시 서버를 명시적으로 지정하여, 클라이언트의 모든 인터넷 트래픽이 프락시 서버를 거쳐서 전송되도록 설정하는 방법을 의미한다. 이 방식에서는 사용자가 직접 프락시 서버의 IP 주소와 포트를 설정해야 한다.
단점
- 수동 프락시 설정은 단순하지만 유연하지 못함
- 단 하나의 프락시 서버만을 지정할 수 있다.
- 장애 시의 대체 작동에 대한 지원이 없다.
- 큰 조직에서는 관리 문제를 야기한다.
2) PAC 파일
프락시 자동 설정(PAC) 파일은 프락시 설정에 대한 동적인 해결책이다.
프락시 설정을 상황에 맞게 계산해주는 작은 JS 프로그램이며, 문서에 접근할 때마다 JS 함수가 적절한 프락시 서버를 선택한다.
PAC 파일 사용 시, 자바스크립트 PAC 파일의 URI를 브라우저에 설정해야 한다. ('자동 설정' 상자에 URI 제공해야 한다.)
브라우저는 URI로부터 PAC 파일을 가져와서 매 접근마다 적절한 프락시 서버를 계산하기 위해 JS 로직을 이용한다.
PAC 파일
- 확장자: `.pac`
- MIME 타입: `application/x-ns-proxy-autoconfig`
- `FindProxyForUrl(url, host)` 함수를 정의해야 한다.
- 함수의 역할: URI에 접근할 때, 사용할 적절한 프락시 서버 계산해준다.
- 함수의 반환값
- DIRECT: 프락시 없이 직접 연결
- PROXY host:port: 지정한 프락시 사용
- SOCKS host:port: 지정한 SOCKS 서버 사용
프락시 자동 설정 파일 예시
function FindProxyForURL(url, host) {
if(url.substring(0,5) == 'http:') return "PROXY http-proxy.mydomain.com:8080"
else if(url.substring(0,4) == 'ftp:') return "PROXY ftp-proxy.mydomain.com:8080"
else return "DIRECT"
}
PAC 파일 관련 MDN 문서
3) WPAD
웹 프락시 자동발견(WPAD; Web Proxy Auto-Discovery) 프로토콜는 여러 발견 메커니즘의 상승 전략을 이용해 브라우저에게 알맞은 PAC 파일을 자동으로 찾아주는 알고리즘이다.
WPAD 프로토콜 구현 클라이언트가 하게 될 일
- PAC URI를 찾기 위해 WPAD를 사용한다.
- 주어진 URI에서 PAC 파일을 가져온다.
- 프락시 서버를 알아내기 위해 PAC 파일을 실행한다.
- 알아낸 프락시 서버를 이용해서 요청을 처리한다.
PAC 파일을 알아내기 위한 다양한 리소스 발견 기법
- 동적 호스트 발견 규약(DHCP)
- 서비스 위치 규약(SLP)
- DNS 잘 알려진 호스트명
- DNS SRV 레코드
- DNS TXT 레코드 안의 서비스 URI
WPAD는 성공할 때까지 각 기법을 하나씩 시도한다.
프락시 요청의 미묘한 특징들
1) 프락시 URI는 서버 URI와 다르다.
웹 서버와 프락시 메시지 문법은 같지만 예외가 있다.
클라이언트가 프락시 대신 서버로 요청을 보내면 요청의 URI가 달라진다.
클라이언트 ➡️ 웹 서버
GET /index.html HTTP/1.0
User-Agent: SuperBrowserv1.3
스킴, 호스트, 포트번호가 없는 부분 URI를 가진다.
클라이언트 ➡️ 프록시
GET http://www.mary.com/index.html HTTP/1.0
User-Agent: SuperBrowserv1.3
완전한 URI를 갖는다.
서버와 프락시가 다른 요청 형식을 갖는 이유
- 원래의 HTTP에서는 클라이언트는 단일한 서버와 직접 대화했었으므로, 가상 호스팅은 존재하지 않았고 프락시에 대한 대비도 없었다. 단일 서버는 자신의 호스트명과 포트번호를 알고 있으므로 클라이언트는 부분 URI만 보내도 되었다.
- 프락시는 목적지 서버와 커넥션을 맺어야 하므로 서버의 이름을 알 필요가 있었다.
프락시 기반 게이트웨이는 FTP 리소스나 그 외의 스킴과 연결하기 위해 URI 스킴을 알 필요가 있었다.
서버로는 부분 URI를, 프락시로는 완전한 URI를 보낼 필요가 있다.
2) 가상 호스팅에서 일어나는 같은 문제
가상 호스팅 웹서버는 여러 웹 사이트가 같은 물리적 웹 서버를 공유한다.
요청 하나가 부분 URI /index.html으로 오면 가상으로 호스팅되는 웹 서버는 그 요청이 접근하고자 하는 웹사이트의 호스트명을 알 필요가 있다.
해결 방법
- 명시적인 프락시는 요청 메시지가 완전한 URI를 갖도록 하여 문제를 해결한다.
- 가상으로 호스팅되는 웹 서버는 Host 헤더를 요구
Host 헤더에는 호스트와 포트에 대한 정보가 담겨있다.
3) 인터셉트 프락시는 부분 URI를 받는다.
클라이언트가 프락시를 사용한다고 설정되어 있지 않더라도 클라이언트의 트래픽은 대리 프락시나 인터셉트 프락시를 지날 수 있다.
두 가지 경우, 클라이언트는 자신이 웹 서버와 대화하고 있다고 생각하고 부분 URI를 보낸다.
4) 프락시는 프락시 요청과 서버 요청을 모두 다룰 수 있다.
트래픽이 프락시 서버로 리다이렉트 될 수 있는 방법은 많으므로, 다목적 프락시 서버는 요청 메시지의 완전한 URI와 부분 URI를 모두 지원해야 한다.
명시적인 프락시 요청에 대해 완전 URI를 사용하고, 그렇지 않다면 부분 URI를 사용해야 한다. 웹 서버 요청의 경우에는 가상 Host 헤더를 사용해야 한다.
완전 URI / 부분 URI 사용 규칙
- 완전 URI인 경우, 프락시는 이를 사용한다.
- 부분 URI + Host 헤더인 경우, Host 헤더를 이용해 원 서버의 이름과 포트번호를 알아내야 한다.
- 부분 URI인 경우, 원 서버를 알아내야 한다.
- 프락시가 원 서버를 대신하는 대리 프락시인 경우, 프락시에 실제 서버의 주소와 포트 번호가 설정되어 있을 수 있다.
- 이전에 어떤 인터셉트 프락시가 가로챈 트래픽을 받았고, 그 인터셉트 프락시가 원 IP 주소와 포트번호를 사용할 수 있도록 해둔 경우 그 IP 주소와 포트번호를 사용할 수 있다.
- 모두 실패한 경우, 에러 메시지를 반환한다.
5) 전송 중 URI 변경
프락시 서버는 요청 URI의 변경에 신경써야 한다. 사소한 URI 변경이라도 문제를 발생시킬 수 있다.
일반적으로 프락시 서버는 가능한 한 관대하도록 애써야 한다. 그들은 프로토콜을 엄격하게 준수하도록 강제해서는 안된다. 이는 기존에 동작하던 기능들을 심각하게 망가뜨리는 결과를 수반할 수 있기 때문이다.
6) URI 클라이언트 자동확장과 호스트명 분석(Hostname Resolution)
브라우저는 프락시의 존재 여부에 따라 요청 URI를 다르게 분석한다.
프락시가 없는 경우, 사용자가 타이핑한 URI를 가지고 그에 대응하는 IP 주소를 찾는다. 호스트가 발견되면 그에 대응하는 IP 주소를 연결에 성공할 때까지 시도해본다.
호스트가 발견되지 않는다면, 자동화된 호스트명의 '확장'을 제공하게 된다.
7) 프락시 없는 URI 분석(URI Resolution)
위 그림은 프락시 없는 브라우저 호스트명 자동확장을 보여준다.
2a~3c는 브라우저에서 유효한 호스트명이 발견될 때까지 다양한 호스트명의 가능성들을 검색한다.
8) 명시적인 프락시를 사용할 때의 URI 분석
명시적인 프락시가 있는 경우, 브라우저는 부분 호스트명을 자동확장하지 않는다.
명시적인 프락시를 사용한다면, 브라우저는 편리한 확장들 중 어느 것도 더 이상 수행할 수 없다. 브라우저의 URI가 프락시를 그냥 지나쳐버리기 때문이다.
브라우저는 명시적인 프락시가 있는 경우 부분 호스트명을 자동확장하지 않으므로, 사용자가 브라우저의 위치 창에 'oreilly'라고 검색했을 때, 프락시는 'http://oreilly/'라고 보낸다. (스킴과 경로는 추가하지만 호스트명은 그대로이다)
9) 인터셉트 프락시를 이용한 URI 분석
인터셉트 프락시를 거친다면, 호스트명 분석은 이전의 방식과 달라진다. 클라이언트의 입장에서 프락시는 모르는 입장이기 때문이다.
인터셉트 프락시를 사용하고 있는 브라우저는 죽은 서버의 IP 주소를 탐지할 수 없다.
- 단계 1: 사용자는 브라우저 URI 검색 창에 'oreilly'라고 타이핑한다.
- 단계 2a: DNS를 통해 찾아보지만, 단계 2b에서 실패하고 호스트는 알 수 없다고 응답한다.
- 단계 3a: 브라우저는 'oreilly'를 'www.oreilly.com'으로 변환하는 자동확장을 한다. 단계 3b에서 브라우저는 DNS를 통해 해당 호스트를 찾아보고, 단계 3c에서는 성공하여 IP주소를 브라우저에게 반환한다.
- 단계 4a: 클라이언트는 이미 성공적으로 호스트명을 분석하였고, IP 주소의 목록을 갖고 있다. 일반적으로 클라이언트는 성공할 때까지 모든 IP 주소에 대한 접속을 시도하지만 IP 주소가 죽었다면, 첫 번째 접속 시도는 원 서버가 아닌 프락시 서버에 의해 종료된다. 클라이언트는 성공적으로 웹 서버와 대화했다고 믿지만 웹 서버는 살아있지 않았다.
- 단계 5b: 프락시가 최종적으로 진짜 원 서버와 상호작용할 준비가 되었을 때, 프락시는 그 IP 주소가 실제로 다운된 서버를 가리키고 있음을 알게 될 것이다. 프락시는 호스트 헤더에 들어있는 호스트명을 분석하거나 역방향 DNS 룩업을 통해 다른 IP 주소를 시도해야 한다.
메시지 추적
웹 요청이 클라이언트에서 서버로 향하는 도중에 둘 이상의 프락시를 지나게 된다.
프락시가 점점 더 흔해지면서 서로 다른 스위치와 라우터를 넘나드는 IP 패킷의 흐름 추적 못지않게 프락시를 넘나드는 메시지의 흐름을 추적하고 문제점을 찾아내는 것도 중요하다.
1) Via 헤더
Via 헤더 필드는 메시지가 지나는 중간 노드(프락시, 게이트웨이)의 정보를 나열한다.
메시지가 또 다른 노드를 지날 때마다, 중간 노드는 Via 목록의 끝에 반드시 추가되어야 한다.
예시
Via: 1.1 proxy-62.irenes-isp.net, 1.0 cache.joes-hardware.com
위 문자열은 메시지가 2개의 프락시를 지나갔음을 말해준다.
첫 번째 프락시는 HTTP/1.1 프로토콜을 구현했으며, proxy-62.irenes-isp.net이라고 불린다.
두 번째 프락시는 HTTP/1.0을 구현했고, cache.joes-hardware.com으로 불린다.
Via 헤더 필드는 메시지의 전달을 추적하고, 메시지 루프를 진단하고 요청을 보내고 그에 대한 응답을 돌려주는 과정에 관여하는 모든 메시지 발송자들의 프로토콜 능력을 알아보기 위해 사용된다.
프락시는 또한 네트워크의 라우팅 루프를 탐지하기 위해 Via 헤더를 사용할 수 있다. 프락시는 요청을 보내기 전에 자신을 가리키는 유일한 문자열을 Via 헤더에 삽입해야 하며, 네트워크에 라우팅 루프가 있는지 탐지하기 위해 문자열이 들어온 요청에 있는지 검사해야 한다.
Via 문법
쉼표로 구분된 경유지(waypoint)의 목록
각 경유지는 개별 프락시 서버나 게이트웨이 홉을 나타내며 그들 중간 노드의 프로토콜과 주소에 대한 정보를 담고 있다.
Via 헤더의 형식 구문
Via = "Via" ":" (waypoint) [", " ( waypoint )...]
waypoint = ( received-protocol received-by [ comment ] )
received-protocol = [ protocol-name "/" ] protocol-version
received-by = ( host [ ":" port ] ) | pseudonym
프로토콜 이름
프로토콜이 HTTP라면 이름은 없어도 된다.
비 HTTP 프로토콜은 게이트웨이가 다른 프로토콜을 위해 HTTP 요청에 접속할 때 발생할 수 있다.
프로토콜 버전
노드 이름
중개자의 호스트와 포트번호
* 포트 번호는 선택적인 요소
노드 코멘트
중개자 노드를 서술하는 선택적인 코멘트
Via 요청과 응답 경로
요청 메시지와 응답 메시지 모두 프락시를 지나므로 둘 모두 Via 헤더를 가진다.
요청과 응답은 보통 같은 TCP 커넥션을 오가므로, 응답 메시지는 요청과 같은 경로로 되돌아간다.
Via와 게이트웨이
몇몇 프락시는 서버에게 비 HTTP 프로토콜을 사용할 수 있는 게이트웨이 기능을 제공한다.
Via 헤더는 이러한 프로토콜 변환을 기록하므로, HTTP 애플리케이션은 프락시 연쇄에서 프로토콜 능력과 변환이 있었는지 알아챌 수 있다.
Server 헤더와 Via 헤더
Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려준다. Server 헤더는 원 서버를 위해 존재한다.
예시
Server: Apache/1.3.14 (Unix) PHP/4.0.4
Server: Netscape-Enterprise/4.1
Server: Microsofr-IIS/5.0
응답 메시지가 프락시를 통과할 때 프락시는 Server 헤더를 수정해서는 안된다.
Via가 개인정보 보호와 보안에 미치는 영향
보안을 위한다면 Via 노드를 익명으로 교체해야한다.
아주 강력한 보안을 위해 프락시는 정렬된 일련의 Via 경유지 항목들을 하나로 합칠 수 있다.
- 여러 경유지들이 모두 같은 조직의 통제하에 있고, 호스트가 가명으로 교체되지 않는 이상 항목을 합쳐서는 안된다.
- 수신된 프로토콜 값이 서로 다른 항목도 합쳐서 안된다.
// AS-IS
Via 1.0 foo, 1.1 devirus.company.com, 1.1 access-logger.company.com
// TO-BE
Via: 1.0 foo, 1.1 concealed-stuff
2) TRACE 메서드
프락시가 점점 복잡해지고 많은 벤더가 프락시 제품을 배치하면서 상호운용성 문제가 증가한다.
프락시 네트워크를 진단하기 위해 HTTP 프락시 네트워크를 통해 홉에서 홉으로 전달될 때마다 메시지의 내용이 어떻게 변하는지 편리하게 관찰할 방법이 필요하다.
TRACE 메서드는 요청 메시지를 프락시의 연쇄를 따라가면서 어떤 프락시를 지나가고 각 프락시가 어떻게 요청 메시지를 수정하는지 관찰/추적할 수 있도록 해준다.
TRACE 요청이 목적지 서버에 도착했을 때, 서버는 전체 요청 메시지를 HTTP 응답 메시지의 본문에 포함시켜 송신자에게 그대로 돌려보낸다. TRACE 응답이 도착했을 때, 클라이언트는 서버가 받은 메시지와 그 메시지가 지나간 프락시들의 목록(Via 헤더 내의)을 검사할 수 있다.
- TRACE 응답의 `Content-Type`은 `message/http`이며, 상태는 `200 OK` 이다.
Max-Forwards
일반적으로 TRACE 메시지는 중간에 프락시들이 몇 개 있든 신경쓰지 않고 서버로의 모든 경로를 여행한다.
TRACE와 OPTIONS 요청의 프락시 홉(hop) 개수를 제한하기 위해 Max-Forwards 헤더를 사용할 수 있다.
- 전달되는 메시지가 무한 루프에 빠지지 않는지 테스트
- 연쇄 중간의 특정 프락시 서버들의 효과를 체크할 때 유용하다.
Max-Forwards 요청 헤더 필드는 이 요청 메시지가 몇 번 더 다음 홉으로 전달될 수 있는지 말해주는 정수 하나를 담고 있다.
- 만약 Max-Forwards 값이 0이라면 수신자는 자신이 원 서버가 아니라 할지라도 TRACE 메시지를 더 이상 전달하지 말고, 클라이언트에게 돌려줘야 한다.
- 받은 Max-Forwards 값이 0보다 크다면, 전달된 메시지의 Max-Forwards 필드는 반드시 1 감소된 값으로 갱신되어야 한다.
프락시 인증
프락시는 접근 제어 장치로서 제공될 수 있다.
HTTP는 사용자가 유효한 접근 권한 자격을 프락시에 제출하지 않는 한 콘텐츠에 대한 요청을 차단하는 프락시 인증이라는 메커니즘을 정의하고 있다.
- 제한된 콘텐츠에 대한 요청이 프락시 서버에 도착했을 때, 프락시 서버는 접근 자격을 요구하는 `407 Proxy Authorization Required` 상태 코드를 어떻게 그러한 자격을 제출할 수 있는지 설명해주는 `Proxy-Authenticate` 헤더 필드와 함께 반환할 수 있다.
- 클라이언트는 407 응답을 받게 되면 요구되는 자격을 수집한다.
자격을 획득하면 클라이언트는 요구되는 자격을 Proxy-Authorization 헤더 필드에 담아서 요청을 다시 보낸다.
- 자격이 유효하다면 프락시는 원 요청을 연쇄에 따라 통과시킨다.
유효하지 않다면 407 응답을 보낸다.
프락시 인증은 인증에 참여하는 프락시가 프락시 연쇄 상에 여러 개 있을 때는 일반적으로 잘 동작하지 않는다.
프락시 상호운용성
클라이언트, 서버, 프락시는 HTTP 명세의 여러 버전에 대해 여러 벤더에 의해 만들어진다.
그들이 지원하는 여러가지 기능을 지원하며, 제각각 다른 버그를 갖고 있다.
프락시 서버는 서로 다른 프로토콜을 구현했을 수도 있는 클라이언트와 서버 사이를 중개해야 한다.
1) 지원하지 않는 헤더와 메서드 다루기
프락시 서버는 넘어오는 헤더 필드들을 모두 이해하지 못할 수도 있다.
몇몇 헤더는 프락시보다 최신의 것일 수 있으며, 심지어 특정 애플리케이션 만을 위해 특별히 만들어진 것일 수 있다.
프락시는 이해할 수 없는 헤더 필드는 반드시 그대로 전달해야 하며, 같은 이름의 헤더 필드가 여러 개 있는 경우에는 그들의 상대적인 순서도 반드시 유지해야 한다.
그리고, 지원하지 않는 메서드 또한 통과시켜야 한다.
2) OPTIONS: 어떤 기능을 지원하는지 알아보기
HTTP OPTIONS 메서드는 서버나 웹 서버의 특정 리소스가 어떤 기능을 지원하는지를 클라이언트가 알아볼 수 있게 해준다.
서로 다른 기능 수준의 서버와 프락시가 더 쉽게 상호작용할 수 있도록 클라이언트는 OPTIONS를 이용해 서버의 능력을 먼저 알아낼 수 있다.
서버가 지원하는 메서드를 찾기 위해 OPTIONS 사용하기
예시
만약 OPTIONS 요청의 URI가 별표(*)라면 요청은 서버 전체에 능력에 대해 묻는다.
OPTIONS * HTTP/1.1
URI가 실제 리소스라면 OPTIONS 요청은 특정 리소스에 대해 가능한 기능들을 묻는 것이다.
OPTIONS http://www.joes-hardware.com/index.html HTTP/1.1
static HTML file wouldn't accept a POST method.
성공한다면, 200 OK 응답을 반환한다.
하지만 HTTP/1.1이 명시한 헤더는 서버에 의해 어떤 메서드가 지원되는지 서술하는 Allow 헤더 하나 뿐이다.
3) Allow 헤더
Allow 엔티티 헤더 필드는 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드들이나 서버가 지원하는 모든 메서드(요청 URI가 *인 경우)를 열거한다.
Allow: GET, HEAD, PUT
Allow 헤더는 새 리소스가 지원했으면 하는 메서드를 추천하기 위해 요청 헤더로 사용될 수 있다. 그러나 서버는 추천 받은 메서드를 모두 지원해야 할 의무는 없다.
요청에 대한 응답으로 실제로 지원하는 메서드들을 열거하는 Allow 헤더를 포함시켜야 한다.
프락시는 Allow 헤더 필드를 수정할 수 없다.