웹 프락시 서버는 클라와 서버 사이 사이에 위치하여 그들 사이의 HTTP 메시지를 정리하는 중개인으로 동작함.
프락시 기능, 동작을 포함해 HTTP 프락시 서버의 모든 것을 다뤄보자.
웹 프락시란?
- 웹 중개자임.
- 프락시는 웹 클라에서 볼 때 서버처럼 동작해야 하고, 웹 서버에서 볼 때 클라처럼 동작하면서 요청와 응답 메시지를 돌려줘야 함.
- 트랜잭션을 완료하는 것은 클라와 서버라는 점은 변하지 않지만, 프락시가 제공하는 좋은 서비스를 이용할 수 있음.
- 프락시는 2개로 나뉨.
- 개인 프락시
- 하나의 클라만을 위한 프락시.
- ISP 서비스와 마찬가지로 브라우저의 기능을 확장하거나 성능을 개선하거나 무료 ISP 서비스를 위한 광고를 운영하기 위해 작은 프락시를 사용자의 컴퓨터에서 직접 실행함.
- 공용 프락시
- 여러 클라가 함께 사용하는 프락시.
- 대부분의 프락시가 여기에 해당함. 중앙 집중형 프락시를 관리하는 게 더 비용효율이 높고 쉽기 때문. 그리고 캐시 프락시 서버와 같은 몇몇 프락시 애플리케이션은 프락시를 이용하는 사용자가 많을 수록 유리함.
프락시 vs 게이트웨이

- 프락시 : 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결.
- 게이트웨이 : 서로 다른 프로토콜을 사용하는 둘 이상을 연결. 서로 간의 트랜잭션을 완료할 수 있도록 해주는 프로토콜 변환기처럼 동작함.
- 하지만 프락시는 브라우저와 서버가 다른 버전의 HTTP를 구현하는 경우 또는 상용 프록시는 SSL 보안 프로토콜, SOCKS 방화벽, FTP 접근, 웹 기반 애플리케이션을 지원하는 경우 등 게이트웨이 기능을 구현할 때도 있어 차이점이 모호함.
왜 프락시를 사용할까?
- 보안 개선
- 성능 향상
- 비용 절약
- 트래픽 감시, 수정 (모든 HTTP 트래픽 접근 가능)
- 등 실용적이고 유용한 것이라면 무엇이든 함.
예를 들어
- 성인 콘텐츠 차단 등의 악성 콘텐츠 식별
- 문서 접근 제어
- 대기업이나 분산된 관료 조직에서 유용함.
- 프락시를 피할 수 없도록 웹 서버가 고정적으로 프락시 서버로부터의 요청만 받아들이도록 설정할 수 있음.
- 보안 방화벽
- 네트워크 보안 엔지니어가 사용.
- 프락시는 응용 레벨 프로토콜의 흐름을 네트워크의 한 지점에서 통제함.
- 바이러스를 제거하는 웹이나 이메일 프락시가 사용할 수 있는, 트래픽을 세심히 살펴볼 수 있는 훅 제공.
- 웹 캐시
- 프락시 캐시는 문서의 로컬 사본을 관리하고 해당 문서에 대한 요청이 오면 빠르게 제공하여, 느리고 비싼 인터넷 커뮤니케이션을 줄임.
- 원 서버보다 웹 캐싱 프락시가 가깝다면 클라는 가까운 웹 캐시의 문서에 접근함.
- 대리 프락시
- 웹 서버의 요청을 받아 요청 받은 콘텐츠의 위치를 찾아내기 위해 다른 서버와 커뮤니케이션함.
- 공용 콘텐츠에 대한 느린 웹 서버의 성능을 개선하기 위해 사용.
- 그래서 서버 가속기(리버스 프락시)로 불리기도 함.
- 콘텐츠 라우팅 기능과 결합되어 주문형 복제 콘텐츠의 분산 네트워크를 만들기 위해 사용됨.
- 콘텐츠 라우터
- 인터넷 트래픽 조건과 콘텐츠의 종류에 따라 요청을 특정 웹 서버로 유도하는 콘텐츠 라우터로 동작함.
- 사용자가 더 높은 성능을 위해 돈을 지불했다면 콘텐츠 라우터는 요청을 가까운 복제 캐시로 전달함.
- 사용자가 필터링 서비스에 가입했다면 HTTP 요청이 필터링 프락시를 통과하도록 할 수 있음.
- 많은 흥미로운 서비스가 맞춤형 콘텐츠 라우팅 프락시를 이용해서 구성될 수 있음.
- 앞서 대리 프락시와 함께 돈을 지불한 사용자에게 복제 캐시로 접근하게 할 수 있음.
- 트랜스코더
- 콘텐츠를 클라에게 전달하기 전에 본문 포맷을 수정함.
- 트랜스코딩이란 데이터의 표현 방식을 자연스럽게 변환하는 것을 말함.
- 크기를 줄이기 위해 gif를 jpg로 변환하거나 색 강도를 줄임. 또한 텍스트 파일 압축, 스마트폰을 위해 텍스트 줄이기, 외국어 문서로 변환이 가능함.
- 익명화 프락시
- HTTP 메시지에서 신원을 식별할 수 있는 특성들(IP 주소, Form 헤더, Referer 헤더, 쿠키, URI 세션 아이디)을 제거함으로써 개인 정보 보호와 익명성 보장에 기여함.
프락시는 어디에 있을까?
어떻게 프락시가 네트워크에 배치될까?
- (개인 LAN) 출구 프락시
- 로컬 네트워크와 더 큰 인터넷 사이 오가는 트래픽을 제어하기 위해 프락시를 로컬 네트워크 출구에 놓을 수 있음.
- ex) 회사에서 해커를 막기위해, 성능을 개선하기 위해 사용, 초등학교에서 성인 콘텐츠를 막기 위해 필터링 출구 프락시 사용.
- (ISP) 접근(입구) 프락시
- 모든 요청을 종합적으로 처리하기 위해 프락시는 ISP 접근 지점에 위치함.
- 보통 캐시 프락시를 사용해 많이 찾는 문서들의 사본을 저장함.
- 대리 프락시
- 네트워크의 가장 끝에 있는 웹 서버들의 바로 앞에 위치하여 웹 서버로 향하는 모든 요청을 처리하고 필요할 때만 웹 서버에 자원을 요청.
- 보안 기능 추가, 빠른 웹 서버 캐시를 느린 웹 서버의 앞에 놓음으로써 성능 개선.
- 웹 서버의 이름과 IP 주소로 스스로를 가장하기 때문에 모든 요청은 서버가 아닌 프락시로 감.
- 네트워크 교환 프락시
- 캐시를 이용해 인터넷 교차로의 혼잡을 완화하고 트래픽 흐름을 감시하기 위해 네트워크 사이의 인터넷 피어링 교환 지점에 놓일 수 있음.
- 주요 프락시들은 보통 인터넷 대역폭이 매우 비싼 곳(ex 유럽)에 배치됨.
어떻게 프락시의 연쇄가 계층을 이룰까?

- 프락시들은 프락시 계층이라고 불리는 연쇄를 구성할 수 있음.
- 프락시 계층에서 프락시 서버들은 부모와 자식의 관계를 가짐.
- 인바운드 프락시(서버쪽에 가까운 쪽)를 부모라고 하며, 아웃바운드 프락시(클라이언트에 가까운 쪽)를 자식이라고 부름.
- 그림의 프락시 계층은 정적임. 하지만 프락시 서버는 여러 가지 판단에 근거해 메시지를 다양하고 유동적인 프락시 서버와 원 서버들의 집합에게 보낼 수 있음. ex) 콘텐츠 라우팅, 트랜스코더
- 동적 부모 선택의 몇 가지 예시는 다음과 같음.
- 부하 균형
- 자식 프락시는 부하를 분산하기 위해 현재 부모들의 작업량 수준에 근거하여 부모 프락시를 고름.
- 지리적 인접성에 근거한 라우팅
- 자식 프락시는 원 서버의 지역을 담당하는 부모를 선택할 수 있음.
- 프로토콜/타입 라우팅
- URI에 근거해 다른 부모나 원 서버로 라우팅 할 수 있음.
- 유료 서비스 가입자를 위한 라우팅
- 추가금을 지불한 경우, URI를 대형 캐시나 성능 개선을 위한 압축 엔진으로 라우팅함.
어떻게 트래픽이 올바르게 프락시를 찾아갈까?
클라 트래픽이 프락시로 가도록 만드는 방법에는 4가지가 있음.
- 클라이언트 수정
- 웹 클라는 수동, 자동으로 프락시 설정을 지원함. 클라가 프락시를 사용하도록 설정하면 클라는 HTTP 요청을 원 서버가 아닌 프락시로 보냄.
- 네트워크 수정
- HTTP 트래픽을 지켜보고 가로채어 클라 모르게 프락시를 조정함.
- 이를 인터셉트 프락시(투명 프락시)라고 부르며 트래픽을 보내는 스위칭 장치와 라우팅 장치를 필요로 함.
- DNS 이름 공간 수정
- 웹 서버 앞에 위치하는 프락시 서버인 대리 프락시는 웹 서버의 이름과 IP 주소를 자신이 직접 사용함.
- 그래서 모든 요청은 서버 대신 대리 프락시로 감.
- DNS 이름 테이블을 수동으로 편집하거나 사용할 적절한 프락시나 서버를 계산해주는 동적 DNS 서버를 이용해서 조정될 수 있음.
- 웹 서버 수정
- HTTP 리다이렉션 명령(응답 코드 305)을 클라이언트에게 돌려줌으로써 요청을 프락시로 리다이렉트 하도록 설정할 수 있음.
- 리다이렉트를 받는 즉시 클라는 프락시와의 트랜잭션을 시작함.
클라이언트 프락시 설정 방법
- 수동 설정
- 프락시를 사용하겠다고 명시적으로 설정.
- 프락시의 호스트와 포트를 지정함.
- Ex) 구글 크롬에서는 설정 > 컴퓨터 프록시 설정 열기에서 설정할 수 있음.
- 단순하지만 유연하지 못하단 단점을 가짐. 모든 콘텐츠를 위해 단 하나의 프락시 서버만을 지정할 수 없고, 장애 시의 대체 작동에 대한 지원이 없음. 큰 조직에서 관리하기 어려움.
- 브라우저 기본 설정
- 브라우저 벤더나 배포자가 브라우저를 소비자에게 전달하기 전에 프락시를 미리 설정.
- 프락시 자동 설정(Proxy auto-configuration, PAC)
- 수동 설정의 단점을 동적 지원을 통해 해결함.
- 프락시 설정을 상황에 맞게 계산해주는 작은 JS 프로그램임.
- PAC 파일을 사용하려면, JS PAC 파일의 URI를 브라우저에 설정해야 함.
- 브라우저는 URI로부터 PAC 파일을 가져와 문서에 접근할 때마다 JS 함수가 적절한 프락시 서버를 선택함. 프락시를 쓸지 말지, 어떤 프락시 서버를 쓸지 판단.
function FindProxyForURL(url, host) { if (url.substring(0,5) === 'http:') { // 지정한 프록시를 사용해야함을 의미하는 PROXY host:port return "PROXY http-proxy.mydomain.com:8080"; } else if (url.substring(0,4) === "ftp:" { return "PROXY ftp-proxy.mydomain.com:8080"; } else { // 프락시 없이 연결이 직접적으로 이루어져야함을 의미하는 DIRECT return "DIRECT"; } } // 그외 SOCKS host:port -> 지정한 SOCKS 서버를 사용
- WPAD(Web Proxy Auto-Discovery Protocol) 프락시 발견
- WPAD는 브라우저에게 알맞은 PAC 파일을 다운 받을 수 있는 설정 서버를 자동으로 찾는 알고리즘임.
- 성공할 때까지 각 기법을 하나씩 시도함.
- 동적 호스트 발견 규약 (DHCP)
- 서비스 위치 규약 (SLP)
- DNS 잘 알려진 호스트 명
- DNS SRV 레코드
- DNS TXT 레코드 안의 서비스 URI
- WPAD 프로토콜이 구현된 클라의 할 일은 다음과 같음.
- PAC URI를 찾기 위해 WPAD를 사용 - 주어진 URI에서 PAC 파일을 가져온다. - 프락시 서버를 알아내기 위해 PAC파일을 실행한다. - 알아낸 프락시 서버를 이용해서 요청을 처리한다.
프락시 요청에 대한 오해
프락시 URI는 서버 URI와 다르다
- 원 서버 : 스킴, 호스트, 포트번호가 없는 부분 URI 요청.
- 프록시 : 완전한 URI 요청.
- 가상 호스팅이 존재하지 않았을 때 클라에서 불필요한 정보 발송을 피하기 위해 부분 URI을 썼지만, 프락시가 부상하면서 URI 스킴 등을 알아야 했기에 완전한 URI을 요구함.
- 그렇다면 프록시가 부분 URI 를 받는다면?
- Host 헤더를 보고 없다면 호스트와 포트에 대한 정보가 담겨 있는 Host 헤더를 포함하도록 요청함. (400 Bad Request 에러를 내려줌)
- http/1.1 부터는 모두 host 헤더를 포함하게 됨. (없으면 400 에러)
인터셉트 프락시는 부분 URI를 받는다
- 인터셉트 프락시나 대리 프락시와 같이 클라이언트가 자신이 프락시와 대화하고 있는 지 모르는 경우가 있음.
- 클라는 자신이 웹 서버와 대화하고 있다 생각해 완전한 부분 URI를 전송함.
- 클라에서 프락시로 가는 트래픽을 가로채면 완전한 URI를 받을 수 있지만 자주 일어나지 않는 일임. 인터셉트 프락시가 사용하는 포트번호와 명시적인 프락시가 사용하는 포트번호가 다르기 때문.
프락시는 프락시 요청과 서버 요청을 모두 다룰 수 있다
- 다목적 프락시는 요청 메시지의 완전한 URI와 부분 URI를 모두 지원해야 함.
- 그 규칙은 다음과 같음.
- 완전한 URI가 주어진 경우 프락시는 이것을 사용함.
- 부분 URI가 주어졌고 Host 헤더가 있다면 이를 이용해 원 서버의 이름과 포트 번호를 알아냄.
- 부분 URI가 주어졌으나 Host 헤더가 없다면, 다음의 방법으로 원 서버를 알아내야 함.
- 대리 프락시인경우, 프락시에 실제 서버의 주소와 포트 번호가 설정되어 있을 수 있음.
- 인터셉트 프락시가 원 IP 주소와 포트번호를 사용할 수 있도록 해두었다면 이를 사용함.
- 모두 실패하였다면 에러 메시지를 반환함.
전송 중 URI 변경
- URI의 변경은 다운스트림 서버와 상호 운용성에 문제를 일으킬 수 있기 때문에 신경을 써야함.
- HTTP 프로토콜에 :80을 명시적으로 붙이는 등의 당연한 일도 치명적인 문제를 야기할 수 있음.
- 일반적으로 프락시 서버는 가능한 한 관대하도록 애써야하며 URI의 변경을 최소한으로 하고, 유일한 예외는 빈 경로를
/
로 교체하는 경우임.
URI 클라이언트 자동확장과 호스트 명 분석(Hostname Resolution)
- 브라우저는 프락시의 존재 여부에 따라 요청 URI를 다르게 분석함.
- 프락시가 없다면 사용자가 타이핑한 URI를 가지고 그에 대응하는 IP 주소를 찾음.
- 2장의 확장 URL 사용.
www
와 같은 접두사 및com
접미사를 붙임.- 오타 교정.
- DNS는 호스트 명의 앞부분만 입력하면 자동으로 도메인 검색.
- 명시적 프락시가 있다면 브라우저는 URL 확장을 사용할 수 없음.

- 인터셉트 프락시의 경우 프락시 없는 URI 분석과 크게 다르지 않지만, 서버로의 커넥션이 만들어졌을 때(5b) 아래와 같은 차이가 발생함.
- 만약 죽은 죽은 서버와 접속을 시도할 경우, 죽은 서버의 IP 주소를 탐지할 수 없기에 브라우저에서 제공하는 것과 동등한 수준의 장애 허용을 제공하기 위해 프락시는 호스트 헤더에 들어 있는 호스트 명을 다시 분석하든 아니면 IP 주소에 대한 역방향 DNS 룩업을 해서든 다른 IP 주소를 시도함.
- 인터셉트 프락시와 명시적인 프락시 모두 죽은 서버의 DNS 분석에 대한 장애 허용을 지원해야 한다는 것은 중요함. 브라우저가 명시적인 프락시를 사용하도록 설정되어 있는 경우의 장애 허용은 프락시에 달려있기 때문.
메시지 추적
- 오늘날, 웹 요청 시 둘 이상의 프락시를 지나는 건 흔함. 이에 따라 프락시를 넘나드는 메시지의 흐름을 추적하고 문제점을 찾아내는 것도 필요해짐.
via 헤더
- via 헤더 필드는 메시지가 지나는 중간 노드(프락시, 게이트웨이)의 정보를 나열함. 쉼표로 구별된 경유지(waypoint)의 목록이며 중간 노드의 프로토콜과 주소에 대한 정보를 담고 있음.
- Ex)
via: 1.1 proxy-52.irenes-isp.net, 1.0 cache.joes-hardware.com
- waypoint 구성 요소
- 프로토콜 이름(선택, 기본은 HTTP): 중개자가 받은 프로토콜. 버전 앞에 /로 구분되어 붙음.
- 프로토콜 버전(필수): 수신한 메시지의 버전. ex) 1.0, 1.1
- 노드 이름(필수): 중개자의 호스트와 포트 번호.
- 노드 코멘트(선택): 중개자 노드를 서술하는 선택적인 코멘트.
- 메시지 전달 추적, 메시지 루프 진단, 요청과 응답 과정에 관여하는 모든 메시지 발송자들의 프로토콜을 다루는 능력을 알아보기 위해 사용함.
- 또한 네트워크의 라우팅 루프를 탐지하기 위해 사용함.
- 요청 메시지 응답 메시지 모두 프락시를 지나는 경우 Via 헤더를 가지며 응답 Via는 보통 요청 Via의 반대임.
- 몇몇 프락시는 비 HTTP 프로토콜을 사용할 수 있는 게이트웨이 기능을 제공하고, Via 헤더는 프로토콜 변환을 기록하여 어떤 변환이 있었는지 알아챌 수 있음.
- Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려줌. 이때 프락시는 server 헤더를 수정하면 안됨. server 헤더는 원 서버를 위해 존재함. 대신 프락시는 Via 항목을 추가함.\
- 정확한 호스트 명이 들어가기를 원하지 않는 몇 가지 경우가 있는 경우, 적당한 가명으로 교체해야 함.
TRACE 메서드

- 프락시가 점점 복잡해짐에 따라 프락시 네트워크를 쉽게 진단할 필요가 생김.
- 요청 메시지를 프락시의 연쇄를 따라가면서 어떤 프락시를 지나가고 어떻게 각 프락시가 요청 메시지를 수정하는지 관찰/추적할 수 있도록 하여 프락시 흐름을 디버깅하는데 매우 유용함.
- Trace 응답의 Content-Type은 message/http이며 상태는 200 OK임.
Max-Forwards
로 요청의 프락시 홉(hop) 개수를 제한할 수 있음.- 메시지가 무한 루프에 빠지지 않는지 프락시 연쇄를 테스트하거나 연쇄 중간의 특정 프락시 서버들의 효과를 체크할 때 유용함.
- TRACE 요청에 정수로 표현. 0이라면 수신자는 자신이 원 서버가 아니라 할지라도 TRACE 메시지를 더 이상 전달하지 말고 반드시 클라에게 돌려줌. 0보다 크다면 전달될 메시지의 Max-Fowards 필드는 1 감소된 값으로 갱신됨.
프락시 인증
- 프락시는 접근 제어 장치로서 제공될 수 있음.
- 프락시는 접근 자격을 요구하는 407 Proxy Authorization Required 상태 코드를 어떻게 그러한 자격을 제출할 수 있는지 설명해주는 Proxy-Authenticate 헤더를 통해 어떻게 접근해야 하는 지 알려줌.

- HTTP는 사용자가 유효한 접근 권한 자격을 프락시에 제출하지 않는 한 콘텐츠에 대한 요청을 차단함.
프락시 상호운용성
- 프락시 서버는 서로 다른 프로토콜을 구현했을 수도 있고 이상한 동작을 할 수도 있는 클라이언트와 서버 사이를 중개해야 함.
- 지원하지 않는 헤더와 메서드 다루기
- 프락시는 이해할 수 없는 헤더 필드는 반드시 그대로 전달해야 함.
- 같은 이름의 헤더 필드가 여러 개 있는 경우에 그들의 상대적인 순서도 반드시 유지해야 함.
- OPTIONS: 어떤 기능을 지원하는지 알아보기
- 특정 리소스가 어떤 기능을 지원하는지 클라이언트가 알아볼 수 있게 해줌.
- 성공하면 Allow 헤더를 통해 어떤 메서드가 지원되는지 알려줌.
- ex)
Allow: GET, HEAD, PUT

- Allow 헤더
- 이 필드는 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드들이나 서버가 지원하는 모든 메서드를 열거함.
- Allow 헤더는 리소스가 지원했으면 하는 메서드를 추천하기 위해 요청 헤더로 사용될 수 있으며, 프락시가 지정된 모든 메서드를 이해할 수 없다고 해도 이 필드를 수정할 수 없음.(클라이언트는 원 서버와 대화하는 다른 경로를 갖고 있을 수도 있기 때문)