title: HTTP The Definitive Guide - 06. Proxies
date: 2022-11-18
tags:
- Network
- HTTP
Introduction
GDSC에서 해당 서적을 통해 HTTP를 공부하는 스터디에 참가하고 있다.
HTTP 이전의 내용은 개인적으로 공부하며 채울 예정이다.
이번 Chapter는 06장 Proxies
이다.
Purpose
Proxy의 자세한 동작을 파악한다.
Web Intermediaries
Proxy가 없다면 Client와 Server는 직접적으로 연결한다.
Proxy가 중간에서 Client와 Server를 이어주며, Proxy는 Client 입장에서는 Server가 되며 Server 입장에서는 Client가 된다.
Private and Shared Proxy
Proxy는 하나의 Client에만 사용되거나, 여러 Client에 사용될 수도 있다.
- Public Proxy - 대부분의 Proxy는 여러 Client와 연결되어 공유되는 Proxy이다. 여러 Client와 연결되어 있기에 비용 효율이 좋으며 관리가 편하다. 많은 유저들이 하나의 Proxy를 이용하려고 하기에 Caching 측면에서도 이점이 많다.
- Private Proxy - 하나의 Client에만 연결되어 사용되는 Proxy는 찾아보기 어렵다. ISP (Internet Service Provider)와 같은 서비스에서는 Private Proxy를 이용하여 성능을 추구하거나 무료 ISP 서비스에서 광고를 제공하기 위해 사용하기도 한다.
Proxy vs Gateway
Proxy는 Protocol의 변환 없이 동일한 Protocol로 중개할 때 이용한다.
Gateway는 Protocol의 변환이 필요할 때 사용한다.
하지만 실제로 사용하는 Proxy와 Gateway의 차이는 애매하다.
Browser는 다양한 HTTP Version을 이용하며, 이러한 문제로 인하여 상업적으로 이용하는 Proxy는 Gateway의 기능도 지원을 하여 SSL Protocol, FTP 등의 Protocol을 이용할 수 있도록 한다.
Gateway는 Chapter 08에서 자세히 다룬다.
Why use Proxies?
Proxy는 보안, 성능, 비용 등의 문제를 일부 해결해준다. HTTP를 이용할 때 Proxy를 이용하기에 Traffic을 모니터링할 수 있다.
Child Filter
누구나 모든 컨텐츠를 조회할 수 있으나, 어린아이들에게는 유해할 수 있다.
학교나 가정에서 성인 컨텐츠를 이용할 수 없도록 필터링을 한다.
Document Access Controller
여러 Server나 Internet에 무분별한 접근을 막기 위해 사용한다.
각 Server나 Internet에는 접근 권한이 있어야만 하며, 권한이 없는 Client는 어떠한 일을 벌일지 모르기에 막는다.
Security Firewall
악의적인 공격을 막기 위해 사용한다.
Client가 바이러스가 포함된 무언가를 보낼 수도 있고, Server가 보내는 과정에서 Hooking을 통해 바이러스가 추가될 수도 있다. 이러한 것들을 확인하여 필터링한다.
Hooking은 간단히 Message를 가로채어 악의적인 행위를 한 뒤 다시 보내는 방식으로, 중요 정보 탈취나 바이러스 삽입 등이 가능하다.
Web Cache
Proxy는 자주 사용하는 Resource에 대한 Cache를 가지고 있으며, 이러한 것들을 제공할 때 Server를 거치지 않고 바로 Resource를 넘겨주기에 빠르다.
Surrogate
Surrogate는 Reverse Proxy로도 불리며, Web Server처럼 보인다.
느린 Server의 Content를 여러 Client가 이용할 때, 이를 개선하기 위해 미리 Server에 요청하여 사용하기도 한다. 이 경우 Server Accelerator라고도 불린다.
또한 Content Router와 함께 분산 Network를 구축하기 위해 사용하기도 한다.
Content Router
Internet Traffic에 따라 특정 Server로 Routing한다.
Client 혹은 Server 비싼 비용을 지불하면 Server까지 보내지 않고 복제 Cache에 연결하여 빠르게 Response를 준다.
Transcoder
Response Body의 형식을 Client에 맞추어 변환한 후 보낸다.
사진의 확장자를 바꾸거나 크기를 조절하기도 하고, 텍스트를 압축하거나 요약하기도 하며, Client에 맞게 언어를 바꾸어주기도 한다.
Anonymizer
Client의 Request의 개인 정보 보호를 위해 HTTP Request에서 개인 정보에 해당하는 것들을 없애준다.
물론 Server의 Resource에 접근할 때 이러한 개인 정보가 필요하다면 오히려 문제가 될 수도 있다.
Where do Proxies go?
Proxy는 원하는 곳 어디든지 배치할 수 있으며, 다양한 형태로 존재한다.
- Egress Proxy - Client의 Local Network 끝에 배치하여 Traffic을 조절하거나 필터링한다. Firewall, Child Filter 혹은 Network 이용을 최적화하거나 성능을 높이기도 한다.
- Access (Ingress) Proxy - 위 사진의 ISP Access Proxy에 해당한다. ISP Access 위치에서 Caching을 위해 사용한다.
- Surrogate - Server의 Local Network 끝에 배치하여 Server로 들어오는 Request를 관리한다. 필요할 경우에만 Server에 Request를 넘겨주며, 보안 기능을 넣거나 느린 Server의 Cache로 이용하기도 한다. Server의 이름과 IP Address를 이용하기에 모든 Request는 Server가 아닌 Proxy에게 온다.
Proxy Hierarchy
Client와 Server 사이에 여러 Proxy가 존재하며, 직렬로 여러 Proxy가 연결될 때 Server에 가까운 Proxy부터 부모로 지정이 되며 Client에 가까운 Proxy가 Child가 된다.
Proxy가 항상 Parent로만 전달하지는 않는다. 위 사진과 같이 병렬로 배치될 경우, 조건에 따라 Routing하는 Proxy가 다르다.
Server의 Resource에 접근할 때, 해당 Server가 비용을 많이 냈다면 Cache Server의 동작을 하는 Caching Proxy에게 Request를 넘길 수 있다.
특정 확장자의 사진을 원한다면 압축이 필요하기에 Compressor Proxy로 Request를 넘길 수 있다.
이 외에도 동적으로 Parent를 결정하는 방법은 Product, 설정 파일, 언어, Plugin 등 다양하다.
- Load Balancing - Load Balancing을 위해 부모 Proxy의 작업량에 따라 선택한다.
- Geographic Proximity Routing - 지리학적 위치를 기준으로 부모 Proxy를 선택한다.
- Protocol/Type Routing - URI를 확인하여 기존 Server 혹은 다른 Proxy로 전달한다. 특정 URI는 특수한 Protocol 처리를 위해 특수한 Proxy로 보내질 수 있다.
- Subscription-Based Routing - Publisher가 매우 많은 비용을 지불하였다면 방대한 Cache 혹은 압축 Engine을 탑재한 Proxy로 보내어 성능을 높인다.
How Proxy Get Traffic
일반적으로 Client에서 Server로 전달하나, Proxy를 거치기에 어떻게 Proxy에 전달이 되는지를 알아야 한다.
- Modify the Client - Netscape와 MS Browser와 같은 많은 Web Client는 Proxy Configuration이 존재한다. 이를 수정하여 Server가 아닌 Proxy로 전달이 되도록 할 수 있다.
- Modify the Network - Network의 Infra가 Request를 가로채 Proxy로 보낸다. Client는 이를 알지 못하며 Intercepting Proxy라고도 불린다.
- Modify the DNS Namespace - Surrogate가 Server 앞에 위치하여 Request를 받으며, DNS Naming Table을 수정하거나 동적 DNS Server를 이용하여 Proxy 혹은 Server로 전달되도록 할 수 있다. 실제 Server의 이름이나 IP Address가 바뀌면 기존의 정보를 Surrogate가 가진다.
- Modify the Web Server - Server에서 처리하지 않고 Proxy로 Redirect하도록 할 수 있다. Server에 Request가 도착한 후, Status Code 305를 이용하여 Client는 Response를 본 후 다시 Proxy로 Request를 보낸다.
해당 Chapter에서는 Client Modification만 다루며, 나머지 3개는 Chapter 20에서 자세히 다룬다.
Client Proxy Settings
모든 현대의 Browser는 Proxy 설정을 수정할 수 있도록 다양한 방식을 지원한다.
Manual
많은 Browser는 내부 설정을 통해 Proxy를 명시하여 사용할 수 있다.
일부 ISP는 유저에게 Browser를 제공하기 전에 미리 Proxy 설정을 한다.
PAC (Proxy Auto-Configuration) File
Manual 방식은 간단하지만 하나의 Proxy만 이용하기에 해당 Proxy에 문제가 생기면 유연하게 대응할 수 없다. 또한 방대한 조직에서는 관리 문제가 발생할 수 있다.
여러 Browser를 이용할 경우, 모든 Browser의 Proxy를 변경하는 것은 어렵거나 불가능할 수 있다.
PAC File은 동적으로 Proxy를 선택하여 위의 문제를 해결한다.
JavaScript에 URI를 넘겨주면 해당 URI에서 PAC File을 자동으로 가져온다.
여러 Proxy 중 하나를 선택할 수 있기에 한 Proxy가 뻗어도 다른 Proxy를 이용할 수 있으며, 가장 적절한 Proxy를 선택한다.
Client는 Proxy를 사용할지, 사용한다면 어떠한 Proxy를 사용하는지 결정한다.
각 PAC File은 FindProxyForURI
함수를 선언해야 하며, return 값에 따라 대상이 달라진다.
- DIRECT - Proxy 없이 대상에 직접 연결한다.
- PROXY host : port - 특정 Proxy를 사용한다.
- SOCKS host : port - SOCKS Server를 사용한다.
PAC File에 대한 자세한 내용은 Chapter 20에서 다룬다.
WPAD (Web Proxy Autodiscovery Protocol)
WPAD는 적절한 PAC File을 자동으로 찾는 더 개선된 알고리즘이다.
WPAD는 아래와 같은 동작을 하도록 구현한다.
- PAC URI를 찾는다.
- URI를 통해 PAC File을 가져온다.
- PAC File을 통해 사용할 Proxy를 결정한다.
- Proxy에 Request를 보낸다.
모든 조직에서 모든 기법을 사용할 수 없기에 적절한 Proxy를 찾을 때까지 각 기법을 수행한다.
현재의 WPAD는 아래의 순서대로 기법을 정의하고 사용한다.
- DHCP (Dynamic Host Discovery Protocol)
- SLP (Service Location Protocol)
- DNS의 잘 알려진 Hostname
- DNS SRV Record
- DNS TXT Record의 service URI
잘 모르는 용어들이 사용되었으나, 자세한 건 Chapter 20에서 다룬다.
Tricky Things About Proxy Requests
Proxy 이용에 있어 까다롭거나 Server와 혼동될 수 있는 것들에 대해 알아본다.
URI Differ from Proxy and Server
Client에서 Server로 Request를 보낼 때, URI의 Scheme, Host, Port를 생략하여 보낸다.
하지만 Proxy로 보낼 때는 이러한 것들을 포함한 전체 URI를 보내야 한다.
Server로 직접 보낼 때는 해당 Server로 보내는 것이기에 생략해도 되나, Proxy는 여러 Server와 연결되어 있을 수 있기에 정확한 Server를 명시해주어야 한다.
상단 그림에서는 (b)를 제외한 것들에서는 부분 URI만 보낸다.
(c)는 Surrogate가 Server처럼 동작하기에 생략해도 되는 것이다.
(d)는 Proxy가 Request를 Intercept한다. Client 입장에서는 Server로 보내는 것이기에 URI의 일부를 생략한다. 또한 Client가 Proxy로 보내는 것을 Intercept하기도 하는데, 보통 이러한 경우 전체 URI를 사용하기에 문제가 되지 않는다.
(b)는 중간에 있는 Proxy에 보내며, 해당 Proxy는 여러 Server와 연결되었을 수 있기에 Server를 명시해준다.
HTTP 1.0부터 Proxy에 Request를 보낼 때 전체 URI를 보내도록 하였으며, HTTP 1.1에서는 Server가 전체 URI를 받아도 동작하도록 하였다.
하지만 현재 많은 Server는 부분 URI만 처리하기도 하기에, 이 부분은 Server가 어떤 방식을 지원하냐가 중요할 것이다.
The Same Problem with Virtual Hosting
Virtual Hosted Server도 Proxy와 동일한 문제를 겪는다.
Virtual Hosted Server는 여러 Server와 연결되어 있기에 정확한 Server를 명시해주어야 한다.
Chapter 05의 Virtual Hosted Docroot, Chapter 18의 Virtual Hosting에서 Virtual Hosted Server에 대해 자세히 다룬다.
Proxy를 명시하거나 Header에 Host, Port 정보를 담아 해당 문제를 해결한다.
Proxy Handling Request
Proxy로 Redirect될 때 다양한 Traffic이 들어오기에 Proxy는 이를 모두 지원해야한다.
전체 URI와 부분 URI가 들어올 때 동작은 다르다.
- 전체 URI가 들어온다면 Proxy는 이를 그대로 사용한다.
- 부분 URI가 들어오며 Host Header가 존재한다면 Host Header를 이용하여 보내고자 하는 Server를 특정한다.
- 부분 URI가 들어오며 Host Header가 존재하지 않으면 아래와 같은 방식으로 Server를 특정한다.
- Proxy가 Surrogate라면 Server의 앞에서 Server처럼 동작하기에 뒤에 있는 Server에 전달한다.
- Proxy가 Intercept하였으며 Interceptor가 IP Address와 Port를 알아낸다면, Interception 기술을 통해 Server를 특정한다. 자세한 것은 Chapter 20에서 다룬다.
- 위의 경우가 아니라면 Proxy는 Server를 특정할 수 있는 정보가 없기에 에러 Message를 Response한다.
In-Flight URI Modification
Proxy가 Message를 중개할 때, URI를 변경하지 않도록 해야 한다. 약간의 URI 변화만으로 중개 과정에서 문제가 생길 수 있다.
일부 Proxy는 URI를 표준 형태로 바꾸려고 한다. 생략된 Port를 80으로 명시하거나 잘못된 문자를 대체할 수 있으며, 이 때문에 문제가 발생할 수 있다.
그렇기에 Proxy는 중개하는 Message에 문제가 있는 것처럼 보여도 최대한 이를 건드려서는 안 된다.
특히 HTTP를 이용할 때 Proxy가 중개하는 과정에서 수정하는 것을 금지한다. Path가 지정되지 않았을 경우 /
을 추가하여 Path를 지정하는 것이 유일하게 허용되나, 이 또한 문제가 발생할 수 있기에 건드리지 않는 것이 제일 좋다.
URI Auto Expansion
Browser는 Proxy의 유무에 따라 URI를 명시하는 방식이 다르다.
Proxy가 없다면 입력한 URI를 토대로 Server를 찾는다. Hostname이 발견되면 해당 IP Address와 Connection 맺기를 시도한다.
Host가 발견되지 않는다면 Chapter 02에서 배운 알고리즘을 이용하여 URI를 확장하여 Host를 찾는다.
- 많은 Browser는
www.
와.com
이 없다면 이를 자동으로 추가한다. google을 입력하면 www.google.com으로 확장한다. - 일부 Browser는 Third-Party Site로 URI를 보내 잘못된 철자를 고치거나 입력하고자 하는 URI를 제안해준다.
- DNS 설정은 대부분의 System에서 Host의 일부만 입력하였을 때, Domain을 검색하여 자동으로 완성해준다.
host7.oreilly.com
의 경우,host7
만 입력하여도 URI를 완성해준다. 완전한 전체 URI는 아니지만 사용 가능한 Host이다.
URI Resolution Without Proxy
URI Auto Expansion에서 Proxy 없이 진행되는 과정이다.oreilly
만 입력하였을 경우 우선 이를 DNS를 통해 조회한 후, 알아낼 수 없다면 Auto Expansion한 URI를 조회한다.
DNS에서 해당 URI를 확인하고 대응되는 IP Address를 넘겨주며, Server와 Connection을 맺을 때까지 하나씩 시도한다.
Connection을 맺으면 HTTP Message를 주고받는다.
URI Resolution With Explicit Proxy
Proxy를 명시하였을 때, URI를 이용하여 IP Address를 알아내는 과정이다.
Proxy를 명시하였기에 DNS에서는 URI에 대응되는 Server 대신 Proxy에 대한 정보를 바로 넘겨준다.
Client는 이 정보를 이용하여 Proxy에 연결한다. 이때 URI를 확장하지 않고 보낸다.
그렇기에 Proxy에서는 www.
와 .com
등을 추가하는 편의 기능을 넣으려고 하나, 일반적으로 사용하는 Proxy에서는 개인 유저에게 적합한 무언가를 붙이는 것이 불가능할 수 있다.
URI Resolution With Intercepting Proxy
Intercepting Proxy의 경우, Proxy가 없을 때 DNS를 통해 Server의 정보를 얻어내는 것까지는 동일하다.
이후 동작은 조금 다르다. Server와 Connection이 맺어질 때까지 각 IP Address를 이용하지만, Intercepting Proxy가 이를 가로채 Client는 바로 Server와 연결된 것으로 인식한다. 물론 Server가 죽어있더라도 Client는 이를 모른다.
Proxy는 Server와 Connection을 맺어야 하며, 이 과정에서 Server가 죽은 것을 확인할 수도 있다.
Client와 동일한 Fault Tolerance를 제공하기 위해 Host Header의 Hostname을 확인하거나 Reverse DNS를 이용하여 여러 IP Address를 이용하여 Connection을 맺는다.
Intercepting Proxy와 Explicit Proxy 모두 Server가 죽었더라도 DNS를 이용할 수 있도록 Fault Tolerance를 지원해야 하는데, 이는 Explicit Proxy를 이용하는 Browser 설정이 Fault Tolerance에 의존적이기 때문이다.
- Fault Tolerance - 내고장성 혹은 내결함성이라 불리며, 장애가 발생하여도 서비스를 계속 이용할 수 있어야 한다.
Tracing Messages
Client가 Server에 도착하기까지 여러 Proxy를 거치는 것은 흔한 일이 되었다.
많은 기업은 보안과 비용 절감, 성능 향상 등을 위해 Caching Proxy를 이용한다. 이 때문에 Surrogate를 두어 Caching을 하는 비율도 증가하였다.
Proxy는 여러 Vendor에 의해 만들어지며, 이러한 Proxy는 각자 다른 기능을 가지고 다양한 조직에서 관리한다.
Proxy 사용은 당연한 것이 되어버렸으며, Packet의 흐름을 파악하여 문제를 해결할 수 있어야 한다.
Via Header
Via Header에는 Message가 목적지에 도착하기 전에 거쳐 간 장치들을 기록한다.
HTTP의 Version, 그리고 장치의 이름을 순서대로 기록하여 Message의 흐름을 확인할 수 있다. Routing Loop 문제가 발생하면 Via Header를 확인하여 이를 알아낼 수 있다.
위와 같은 Syntax가 존재한다.
1#은 1개 이상이라는 의미이며, ()는 반드시 존재하는 것이다. []는 선택적으로 존재할 수 있으며, | 는 or와 동일하다고 보면 된다.
Via는 waypoint가 n개 존재한다.
waypoint는 Protocol의 정보, Host의 이름, 선택적인 Comment로 존재한다.
Protocol의 정보는 HTTP가 아니라면 PROTOCOL/ 이 붙어야 한다. 그 뒤에는 Protocol의 Version을 명시한다.
Host의 이름은 Host 이름 + 선택적인 Port 표기, 혹은 해당 장치를 편하게 부르는 명칭이다.
Via는 거쳐 간 순서대로 앞에서부터 쌓인다. A, B, C라는 Proxy를 이용하여 왕복하였다면 Via는 Via:VERSION A, VERSION B, VERSION C
/ Via:VERSION C, VERSION B, VERSION A
처럼 작성된다.
일부 Proxy는 Gateway의 기능도 가지고 있다.
Via는 이러한 Gateway로 인하여 Protocol이 변환되는 것도 기록하기에 Message의 흐름을 자세하게 확인할 수 있다.
Server는 Response에 Server Header를 작성하기도 한다. Server의 정보를 적어주며, Via Header에는 Server에 대한 것이 작성되지 않는다.
Proxy가 Firewall의 일부라면 해당 Proxy에 대한 명확한 정보는 Via에 기록되어서는 안 된다. 이러한 정보를 이용하여 악의적인 공격을 받을 수 있다. 기록하고 싶다면 따로 명시를 해주어야 한다.
명시하는 경우를 제외하고는 보안과 관련이 있는 Proxy는 다른 명칭으로 기록되어야 한다.
매우 강한 규제를 하는 조직에서는 이러한 Proxy들을 하나로 합쳐서 기록하기도 한다. 한 조직에서만 다루는 Proxy이며 각 Proxy는 실제 명칭이 아닌 다른 명칭으로 기록될 때만 이를 합쳐서 기록할 수 있다.
TRACE Method
Proxy를 지나갈 때마다 Header는 변할 수 있으며, 다양한 Vendor에서 다양한 Proxy를 배포하기에 호환성이 중요해진다.
Network의 흐름에 따라 Message의 변화를 파악할 수 있어야 하며, 이때 사용하는 것이 TRACE Method이다.
HTTP 1.1에서 TRACE Method가 추가되었으며, Server에 도달할 때까지 거쳐 간 장치들과 Message가 최종적으로 어떻게 도달하는지 알 수 있다.
TRACE Method의 Content-Type은 message/http 이며 Status Code로 200을 받는다.
Max-Forwards Header가 없다면 TRACE Method는 Server에 도달하였을 때의 Message를 알려준다.
이 Header를 이용하면 잘못된 흐름으로 인하여 Message가 Server에 도달하지 못하고 Loop에 갇히는 것을 파악할 수 있다.
Max-Forwards의 값이 0이라면 Server에 도달하기도 전에 바로 Response를 받으며, 0보다 크면 해당 횟수만큼 장치를 거친다.
Proxy Authentication
Proxy는 인증받은 유저의 Request인지 확인한다. 인증이 필요한 Resource에 대한 Request를 받는다면 어떠한 자격이 필요한지와 Stauts Code 407을 Response한다.
Client는 이에 맞는 정보를 찾아 다시 Request를 하며, 인증이 되었다면 Proxy는 Request 처리를 정상적으로 한다. 인증이 되지 않는다면 여전히 Status Code 407을 Response한다.
여러 Proxy를 거쳐야 할 때는 인증이 잘 되지 않으며, 이를 해결하기 위한 개선된 방안을 제안하였으나 널리 사용되지는 않았다.
Chapter 12에서 HTTP 인증에 대해 자세히 다룬다.
Proxy Interoperation
Client, Server, Proxy는 여러 Vendor에 의해 만들어지고 배포된다. 각자 다른 기능을 지원하고 다른 버그가 존재한다. 이를 중개하는 Proxy는 이러한 문제들을 최대한 신경 쓰지 않아야 한다.
Version의 차이, 각 Application에서 수정한 Header, 중복된 Header 등 Proxy가 해석할 수 없는 내용이 존재할 수 있다.
이러한 것들은 Client와 Server를 위한 것들이기에 Proxy는 해석이 불가능하더라도 변경 없이 이를 그대로 중개해주어야 한다.
OPTION Method
OPTION Method는 Chapter03에서 다뤘듯이, Server에서 지원하는 Method를 알아낼 수 있다.
URI가 Asterisk (*) 라면 전체 Server에서 지원하는 Method를 묻는 것이다.
OPTION Method가 잘 작동한다면 Status Code 200과 함께 지원되는 Method의 목록을 Allow Header에 넣어 Response로 받는다.
Allow Header는 Request에서 새로운 Resource에 대해 이러한 Method를 지원해달라는 의미로 사용될 수 있으나, 이러한 Method 지원은 Server의 재량이다.
Conclusion
Client와 Server 사이에 존재하는 Proxy에 대해 학습할 수 있었다.
Client와 Server는 물론 많이 존재하지만, 이를 중개하는 과정은 매우 복잡하며 이러한 것들을 Proxy로 해결한다는 것이 놀라웠다.
Proxy에 대한 표준을 설정하고 이를 무조건 지킨다면 Proxy 사용이 더 용이해질 것 같으나, Network의 발전에 유연하게 대응이 어려울 수도 있을 것 같다.
'Network' 카테고리의 다른 글
HTTP The Definitive Guide - 08. Integration Points: Gateways, Tunnels, and Relays (0) | 2022.11.23 |
---|---|
HTTP The Definitive Guide - 07. Caching (0) | 2022.11.22 |
HTTP The Definitive Guide - 05. Web Servers (0) | 2022.11.10 |
HTTP The Definitive Guide - 04. Connection Management (0) | 2022.11.07 |
HTTP The Definitive Guide - 03. HTTP Messages (0) | 2022.11.04 |