네트워크를 공부하다 보면 프록시란 단어가 계속 나온다. 질리도록 나오고 꼭 필수로 알아야 하는 개념이다.
프록시의 대표적인 예시로 VPN 서버가 있다.
대표적인 예시로 유튜브를 보다 보면 어떤 콘텐츠는 한국에서는 볼 수 없지만 미국에서는 볼 수 있는 경우가 있다.
이럴 때 프록시 서버를 이용해 미국 서버를 통해 접속하면 해당 콘텐츠를 볼 수 있다. 이런 방법은 지역 제한을 우회하는 데 사용된다.
물론 VPN은 보안과 프라이버시 측면에서 더 높은 수준의 보호를 제공하나 어쨋든 프록시 역할을 한다.
그렇다면 프록시가 뭘까?
네트워크의 다양한 구조 중 꼭 알아야 할 구조가 있다.
인라인, 인라인인데 out of path, 그리고 어플리케이션 프록시 구조이다. 이는 뒤에 설명하겠다.
여기서 한 대의 PC가 인터넷에 연결되어있다고 치고, 네이버와 같은 사이트에 접속하고자 할 때의 상황을 살펴 보자.
여기서 말하는 내용은 널널한 개발자 tv의 영상에서 얻은 정보를 기반으로 하고 있다.
https://www.youtube.com/watch?v=dThqHi8-MiQ&t=2s
기본 연결 과정
먼저, 한 PC가 인터넷에 접속하여 네이버에 접속하려고 한다.
이 PC의 IP 주소는 3.3.3.3, 네이버의 IP 주소는 5.5.5.5라고 가정하자.
내 PC인 3.3.3.3 호스트는 5.5.5.5 호스트에게 TCP/IP 프로토콜을 사용하여 연결을 시도한다.
이 과정에서 소켓 통신이 일반적으로 사용된다.
※ 소켓 통신이란?
- 소켓은 네트워크 상의 두 프로세스 간에 데이터 통신을 가능하게 하는 소프트웨어 구조체이다. IP 주소와 포트 번호를 사용하여 서로 연결된 엔드포인트를 정의한다. 소켓을 통해 애플리케이션이 데이터를 송수신할 수 있다.
- 소켓 통신이란 네트워크를 통해 두 컴퓨터 간에 데이터를 교환할 수 있게 해주는 통신 방식이다. 소켓을 통해 연결된 애플리케이션 간의 데이터 전송을 처리한다.
- TCP/IP 프로토콜을 기반으로 하며, 클라이언트와 서버 간의 양방향 통신을 지원한다.
프록시를 통한 연결 과정
이제, 상황을 조금 변형시켜서 두 대의 PC가 있다고 생각하자. 각각 PC1, PC2의 이름을 부여하겠다.
PC2의 IP 주소는 9.9.9.9이다. PC1이 인터넷에 접속하여 특정 사이트에 접속하고자 할 때, PC1은 직접 네이버에 접속하는 대신 PC2를 프록시 서버로 설정한다.
이 설정에 따라, PC1은 먼저 프록시 서버인 PC2에 접속하고, 이 프록시 서버(PC2)가 네이버에 대신 접속하게 된다.
이 구조에서 프록시는 말 그대로 대리자의 역할을 수행한다. (Proxy란 단어가 대리자라는 뜻)
프록시 구조의 종류
1. 인라인(inline) 구조:
- 네트워크 트래픽이 서버를 거쳐야만 최종 목적지에 도달할 수 있는 구조.
- 프록시 서버가 데이터 흐름의 직접적인 경로상에 위치한다는 의미이다.
2. 인라인인데 Out of Path 구조:
- 이 구조는 인라인 구조와 비슷하지만, 특정 조건이나 상황에 따라 프록시 서버가 네트워크 트래픽을 처리하지 않고 바로 전달할 수도 있다.
- 즉, 프록시가 트래픽의 일부만 처리하는 경우이다.
3. 어플리케이션 프록시 구조:
- 특정 어플리케이션 레벨에서 작동하는 프록시로, HTTP, FTP 등 특정 프로토콜을 위한 프록시 서버이다.
- 어플리케이션 프록시는 더 높은 수준의 필터링, 모니터링 및 접근 제어 기능을 제공한다.
프록시 서버를 사용하는 주된 이유는 보안 강화, 익명성 보장, 콘텐츠 필터링, 캐싱을 통한 성능 향상 등이 있다.

이 그림은 위에서 말한 3.3.3.3의 요청을 9.9.9.9가 받아서 5.5.5.5에 전달하는 그림이다.
위에서도 설명했으나 다시 한 번 이해를 위해 설명하겠다.
프록시 서버는 클라이언트(3.3.3.3)로부터의 요청을 특정 포트에서 기다린다.
클라이언트의 요청이 프록시 서버에 도착하면 프록시 서버는 요청을 처리하거나 수정하지 않고 이를 다른 서버(5.5.5.5)
에 전달한다. 이 과정에서 클라이언트의 요청은 프록시 서버를 통해 전달되는 것이다.
프록시 서버는 서버(5.5.5.5)와의 새로운 소켓 연결을 설정하여 클라이언트의 요청을 최종 서버로 전달한다.
요청의 응답이 돌아오면 프록시는 이를 클라이언트에 다시 연결한다.
결국 중계 역할을 하는 것이다.
여기서 외워야 할 키 포인트가 있다.
유저 모드, 어플리케이션 프록시라는 키워드가 나온다? → 소켓, 스트림
- 유저 모드, 어플리케이션 프록시는 애플리케이션 계층에서의 네트워크 통신을 처리하는 방식과 관련이 있으며, 소켓과 스트림은 이러한 통신 메커니즘을 지원한다.
인라인, Out of Path 라는 키워드가 나온다? → 패킷
- 인라인, Out of Path는 네트워크 보안 장비의 배치 방식과 관련이 있으며, 패킷은 이러한 장비들이 처리하거나 모니터링하는 데이터 단위이다.
둘 다 살고 있는 계층이 다르다.
패킷을 봐야돼. 그럼 proxy일까? 아니다. 인라인, out of path를 생각하자.

설명을 요약한 그림이다.
Proxy를 왜 써야 할까?
그럼 이런 Proxy를 도대체 왜 써야 하는거지?
프록시가 중개 역할을 한다는 것은 알았다. 왜 해야 하는지는 아직 모르겠다. 이제 알아보자.
프록시 서버는 클라이언트(웹 브라우저)와 서버(웹사이트) 사이에 위치하여 중개 역할을 한다는 것을 알았다.
프록시는 이 과정에서 다양한 역할을 수행한다.
1. 캐싱 (Caching)
프록시 서버는 자주 요청되는 데이터를 임시로 저장하는 캐싱 기능을 제공한다.
예를 들어, 웹 사이트의 정적 자원(이미지, CSS 파일, 자바스크립트 파일 등)은 변동이 적기 때문에 이들을 프록시 서버에 저장할 수 있다.
사용자가 특정 웹사이트를 요청할 때, 프록시 서버는 이미 캐시된 데이터를 제공함으로써 서버로의 요청 횟수를 줄이고, 결과적으로 웹 페이지 로딩 시간을 단축시킨다.
네트워크 대역폭 사용을 줄이는 데도 도움이 된다는 뜻이다.
2. 보안 (Security)
프록시 서버는 네트워크 보안을 강화하는 여러 방법을 제공한다.
예를 들어, 악성 웹사이트 접근 차단, 악의적인 파일 다운로드 방지, 공격자로부터 내부 네트워크의 정보를 숨기는 등의 기능을 수행한다.
또한 프록시 서버는 특정 규칙을 설정하여 오직 허용된 요청만을 서버에 전달할 수 있으며, 이는 서버를 보호하고 무단 접근을 차단하는데 효과적이다.
3. 로드 밸런싱 (Load Balancing)
여러 대의 서버를 운영하는 환경에서 프록시 서버는 들어오는 요청을 각 서버에 균등하게 분배하여, 모든 서버가 고르게 부하를 받도록 관리한다.
서버의 과부화를 방지하고, 서비스의 가용성과 성능을 향상시킬 수 있다는 뜻이다.
만약 한 서버가 실패하더라도, 프록시 서버는 요청을 다른 서버로 자동으로 리다이렉션(사용자를 다른 URL로 자동으로 이동시키는 과정)하여 서비스 중단을 최소화할 수 있다.
4. 익명화 (Anonymity)
프록시 서버를 사용하면 사용자의 실제 IP 주소를 숨기고, 대신 프록시 서버의 IP 주소가 보이게 할 수 있다.
사용자의 개인 정보 보호와 익명성을 향상시키는 데 도움이 된다.
예를 들어, 인터넷 사용자가 웹 서핑을 할 때 프록시 서버를 경유하면, 최종적으로 웹사이트에 요청을 보내는 주체가 사용자 본인이 아닌 프록시 서버로 나타나게 된다.
이를 통해 사용자는 자신의 실제 위치나 다른 식별 정보를 노출시키지 않고 익명성을 가지고 인터넷을 사용할 수 있다.
익명화 기능은 또한 특정 지역에서만 제공되는 콘텐츠에 접근하고자 할 때 유용할 수 있다. 예시는 맨 처음에 든 것 처럼 특정 국가에서만 서비스되는 비디어 스트리밍 서비스에 접근하고 싶을 때, 해당 국가에 위치한 프록시 서버를 사용하면, 사용자는 마치 그 국가에 실제로 위치한 것처럼 서비스에 접근할 수 있다.
모든 프록시 서비스가 동일한 수준의 익명성을 제공하는 것은 아니다.
익명성을 보장하기 위해서는 트래픽의 암호화, 로그 정책, 프록시 서버의 신뢰도 등을 고려해야 한다.
또한 완전한 익명성을 위해서는 프록시와 함께 VPN이나 Tor 같은 추가적인 도구를 사용하는 것이 좋다.
5. 접근 제어 (Access Control)
프록시 서버를 통해 특정 웹사이트나 서비스에 대한 접근을 제어할 수 있다.
예를 들어, 기업 환경에서는 직원들이 업무와 관련 없는 사이트에 접근하는 것을 제한하기 위해 프록시 서버를 설정할 수 있다. 업무 효율성을 높일 수 있다.
자녀가 다른 사이트를 접속하지 못하도록 공부시간에 특정 사이트 외의 사이트에 접속을 막는 것도 프록시의 기능이다.

6. 정책 실행 (Policy Enforcement)
프록시 서버는 네트워크 트래픽에 대한 다양한 정책을 실행할 수 있도록 한다.
예를 들어, 회사는 데이터 사용량을 제한하거나 특정 시간대에만 인터넷 사용을 허용하는 등의 정책을 프록시를 통해 적용할 수 있다.
네트워크 자원의 효율적인 관리를 가능하게 하는 것이다.
7. 콘텐츠 필터링 (Content Filtering)
프록시 서버는 특정 키워드나 도메인을 기반으로 콘텐츠를 필터링할 수 있다.
사용자가 접근할 수 있는 웹 콘텐츠를 제어하여 악성 콘텐츠의 전송을 방지하거나 특정 연령대에 부적절한 콘텐츠의 접근을 차단할 수 있다.
이외에도 네트워크 트래픽을 모니터링하고 분석할 수 있는 등의 기능이 있다.
프록시 서버는 단순히 데이터 전송의 중개자 역할을 넘어서 네트워크의 효율송, 보안, 관리 용이성을 크게 향상시킬 수 있는 강력한 도구로 활용되고 있다.
따라서 데이터 전송 시간이나 대역폭 소비와 같은 오버헤드가 있음에도 불구하고 다양한 이점 때문에 많은 조직과 개인이 프록시 서버를 사용하는 것이다.
프록시 예시 코드
파이썬으로 간단한 HTTP 프록시 서버를 구현하는 코드를 만들어보았다.
이 코드는 들어오는 HTTP 요청을 다른 서버로 전달하고 응답을 클라이언트에 반환한다.
나도 코딩 잘 못해서 참고하면서 만들었다.
import http.server # 기본적인 HTTP 서버 제공 모듈
import socketserver # 네트워크 서버를 쉽게 구현할 수 있도록 도와주는 모듈
import urllib.request # URL을 통해 데이터를 요청하고 응답을 받을 수 있는 기능 제공(HTTP/HTTPS 요청을 보내고 응답받을 수 있다)
import urllib.error # urllib.request에서 발생할 수 있는 오류를 처리하기 위한 모듈
class Proxy(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
# 원래 요청 URL
url = self.path[1:]
# 기본적으로 요청할 수 없는 URL에 대한 예외 처리
if not url:
self.send_response(400)
self.end_headers()
return
try:
# 외부 URL에 요청을 보내고 응답을 받음
with urllib.request.urlopen(url) as response:
# 응답을 클라이언트에 반환
self.send_response(response.status)
self.send_header('Content-type', response.headers.get_content_type())
self.end_headers()
self.wfile.write(response.read())
except urllib.error.HTTPError as e:
self.send_response(e.code)
self.end_headers()
self.wfile.write(e.reason.encode())
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(str(e).encode())
PORT = 8000
# HTTP 서버 설정
with socketserver.TCPServer(("", PORT), Proxy) as httpd:
print(f"Serving at port {PORT}")
httpd.serve_forever()
교육용으로 매우 간단한 프록시 서버를 구현한 것이다.
실제 운영 환경에선 보안과 성능 측면에서 훨씬 복잡한 처리가 필요하다.
코드의 동작 방식
- HTTP 요청 수신: Proxy 클래스는 HTTP GET 요청을 수신한다.
- URL 처리: 요청된 URL을 urlopen 함수를 통해 외부 서버로 전송한다.
- 응답 반환: 외부 서버로부터 받은 응답을 클라이언트에 전달한다.
- 예외 처리: 요청이 실패할 경우 적절한 오류 응답을 반환한다.
실행 방법
- 위 코드를 proxy_server.py와 같은 파일로 저장한다.
- Python 3이 설치된 환경에서 터미널을 열고, 해당 파일이 있는 디렉토리로 이동한다.
- python proxy_server.py 명령어를 실행하여 프록시 서버를 시작한다.
- 브라우저에서 http://localhost:8000/ 뒤에 원하는 URL을 추가하여 요청을 보낸다. 예를 들어, http://localhost:8000/www.sungmin.com을 입력하여 www.sungmin.com의 콘텐츠를 가져온다.
여기까지 프록시에 대해 나름 자세히 알아보았다. 읽느라 고생 많았다.
'Network' 카테고리의 다른 글
| 패킷의 생성 원리와 캡슐화 (5) | 2024.08.23 |
|---|---|
| NAT란 무엇일까? (46) | 2024.08.09 |
| 라우터/L3 스위치: 3계층 장비 -2 (37) | 2024.07.27 |
| 라우터/L3 스위치: 3계층 장비 -1 (25) | 2024.07.04 |
| HTTP와 HTTPS는 무슨 차이? (2) | 2024.05.12 |