클라이언트가 서버에 직접 요청을 보내는 구조는 단순하지만, 트래픽이 늘고 서버가 여러 대로 늘어나면 금방 한계에 부딪힌다. Reverse Proxy는 클라이언트와 실제 서버 사이에 위치해 요청을 대신 받고, 적절한 서버로 전달하는 중간자 역할을 한다. 이 구조 하나로 보안, 성능, 유연성을 동시에 확보할 수 있다.
Proxy는 넓은 의미에서 "대리인"을 뜻한다. 일반적으로 Forward Proxy는 클라이언트 측에 위치해 클라이언트를 대신해 외부 서버에 요청을 보낸다. 회사 내부망에서 인터넷 접근을 통제하거나 익명성을 확보할 때 쓰인다.
| 구분 | 위치 | 누구를 대리하나 | 주요 목적 |
|---|---|---|---|
| Forward Proxy | 클라이언트 앞 | 클라이언트 | 접근 제어, 익명화 |
| Reverse Proxy | 서버 앞 | 서버 | 로드 밸런싱, 보안, SSL |
Forward Proxy: 클라이언트 신원을 서버에 숨긴다. Reverse Proxy: 서버 구조를 클라이언트에 숨긴다.
클라이언트
|
| HTTPS 요청 (example.com)
v
[Reverse Proxy: Nginx]
| | |
v v v
[서버 A] [서버 B] [서버 C]
:8001 :8002 :8003
클라이언트는 example.com 하나만 알고 있다. 내부에 서버가 몇 대인지, 어떤 포트를 쓰는지 전혀 모른다. Reverse Proxy가 요청을 받아 내부 서버로 분산시킨다.
SSL Termination은 Reverse Proxy가 HTTPS 연결을 끊고, 내부 서버와는 HTTP로 통신하는 패턴이다. TLS 핸드셰이크와 암복호화 부담을 Reverse Proxy 한 곳에서 처리하므로 내부 서버는 인증서 관리 없이 가벼운 HTTP만 다루면 된다.
클라이언트 → [HTTPS] → Reverse Proxy → [HTTP] → 내부 서버
TLS 종료 여기서
SSL Termination: TLS 세션을 Proxy에서 종료해 내부 네트워크를 단순하게 유지하는 기법.
클라이언트 IP는 Reverse Proxy를 거치면 사라진다. 내부 서버가 실제 클라이언트 정보를 필요로 할 때는 X-Forwarded-For, X-Real-IP 같은 헤더를 통해 전달한다.
X-Forwarded-For: 203.0.113.42
X-Real-IP: 203.0.113.42
X-Forwarded-Proto: https
X-Forwarded-For: 요청이 거친 프록시 IP 목록을 순서대로 기록한다.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://localhost:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
proxy_pass로 내부 서버를 지정하고, proxy_set_header로 원본 클라이언트 정보를 함께 전달한다. SSL 인증서는 Nginx가 단독으로 관리하므로 내부 서버에는 별도 설정이 필요 없다.
단일 서버로 시작하더라도 Reverse Proxy를 앞에 두는 습관은 이후 스케일아웃, 무중단 배포, 인증서 갱신 자동화까지 모두 유연하게 만든다.