proxy server that appears to any client to be an ordinary web server, but in reality merely acts as an intermediary that forwards the client's requests to one or more ordinary web servers
오늘의 주제는 리버스 프록시. 프로젝트 중이었나... 자료조사를 하던 중 연관 개념으로 나왔던 걸 따로 기록해뒀는데, 따로 공부해볼 기회를 마련해보고자 오늘의 주제로 삼았다.
프록시(Proxy) 서버는 클라이언트와 서버 사이에 위치해, 클라이언트의 요청을 대신 처리하거나 서버의 응답을 중계하는 중간 매개체 역할을 수행하는 서버다. 즉, 클라이언트가 직접 목적지 서버에 연결하는 것이 아니라, 프록시 서버를 통해 간접적으로 통신하는 구조를 만든다.
프록시는 요청이 어떤 방향으로 흐르느냐에 따라 Forward Proxy(정방향 프록시) 와 Reverse Proxy(역방향 프록시) 로 나뉜다. 이를 이해하는 것이 프록시 개념의 핵심이다.
기본적인 작동 방식은 다음과 같다:
프록시 서버는 다음과 같은 작업을 수행할 수 있다.
구분 | Forward Proxy | Reverse Proxy |
---|---|---|
위치 | 클라이언트 앞단 | 서버 앞단 |
대상 | 클라이언트가 외부와 통신할 때 사용 | 클라이언트가 서버에 접근할 때 서버 측에서 사용 |
사용 주체 | 사용자, 기업 내부망 사용자 | 서버 운영자, 서비스 제공자 |
주요 목적 | 접근 차단 우회, 캐싱, 익명성 보장 | 부하 분산, 보안강화, SSL 종료, 백엔드 보호 |
예시 | 웹 필터링 프록시, Tor, Squid | NGINX Reverse Proxy, Apache mod_proxy, Cloudflare |
프록시 서버는 사용 위치와 역할에 따라 다양한 기능을 제공하며, 대표적인 목적은 아래와 같다:
리버스 프록시는 클라이언트의 요청을 최종 목적지 서버가 아닌 프록시 서버가 먼저 수신한다. 이를 통해 서버 인프라 뒤편에 위치한 백엔드 서버들의 노출을 막고, 트래픽을 효율적으로 관리할 수 있다.
클라이언트가 도메인 요청 (예: https://example.com
)
리버스 프록시가 클라이언트의 요청을 수신
리버스 프록시가 요청을 내부적으로 적절한 백엔드 서버로 전달
백엔드 서버가 응답 반환 → 프록시 서버가 응답을 수신
프록시 서버가 응답을 클라이언트에게 전달
주의: 클라이언트 입장에선 백엔드 서버의 존재를 인지하지 못함. 오직 프록시만 보임.
https://api.example.com
→ Reverse Proxy → 내부의 http://127.0.0.1:3000
API 서버https://static.example.com
→ Reverse Proxy → 내부의 Nginx 정적 파일 서버리버스 프록시는 백엔드와의 세션/연결을 어떻게 유지하고 관리하느냐에 따라 성능과 안정성이 좌우된다. 일반적인 연결 방식은 다음과 같다:
NGINX
, Apache
, HAProxy
는 keepalive_requests
, keepalive_timeout
등의 설정 지원.주의: 백엔드 서버가 여러 개일 경우, 세션 유지 로직이 없는 상태에서 라운드 로빈 등 단순 분산을 적용하면 사용자 인증 등에서 문제가 발생할 수 있음.
리버스 프록시는 보통 클라이언트에게 도메인으로 접근하게 하며, 이는 DNS 및 포트 설정과 밀접한 연관이 있다.
example.com
, api.example.com
, admin.example.com
등 여러 도메인을 동시에 수신하도록 구성됨.# 예시: /etc/hosts 또는 DNS 설정
203.0.113.1 example.com
203.0.113.1 api.example.com
# 예시: NGINX 리버스 프록시 설정
location /api/ {
proxy_pass http://localhost:3000/;
}
팁: 리버스 프록시와 NAT(Network Address Translation)를 함께 사용할 경우, 내부 IP와 포트를 외부에 노출시키지 않고도 효과적인 서비스 분산이 가능하다.
리버스 프록시는 HTTPS 통신의 SSL/TLS 암호화를 종단(Terminate) 처리함으로써, 백엔드 서버와의 연결은 암호화되지 않은 HTTP로 유지될 수 있도록 한다. 이는 보안과 성능의 균형을 맞추는 중요한 기법이다.
클라이언트와의 통신은 HTTPS로 유지되며, SSL 인증서 및 키는 프록시 서버(Nginx, HAProxy 등)에 배치된다. 프록시가 SSL 암호화를 해제(decrypt)하고, 내부 네트워크로는 HTTP로 요청을 전달한다.
백엔드 서버는 SSL 처리 로직이 필요 없으며, TLS 핸드셰이크에 따른 CPU 부하도 감소한다. 결과적으로 서버 응답 성능이 향상될 수 있다.
모든 SSL 인증서를 리버스 프록시에 집중 배치함으로써, 갱신과 관리가 단순화된다. Let’s Encrypt를 통한 자동 갱신 구성도 용이하다.
단, 내부 네트워크의 보안이 약한 경우에는 프록시 이후 구간도 TLS로 구성하는 "end-to-end encryption"이 고려되어야 한다.
리버스 프록시는 클라이언트 요청을 여러 백엔드 서버로 분산시켜 서비스의 확장성과 가용성을 확보할 수 있게 한다. 이를 로드 밸런싱이라고 한다.
정적 로드 밸런싱 방식
동적 로드 밸런싱 방식
세션 유지 기능 (Session Persistence)
로드 밸런싱은 단순 트래픽 분산 외에도, 장애 대응 및 성능 최적화 전략의 핵심 구성요소
리버스 프록시는 반복적으로 요청되는 정적 리소스(HTML, CSS, JS, 이미지 등)를 자체적으로 캐시하거나 직접 제공하여 백엔드 서버의 부담을 줄일 수 있다.
자주 요청되는 정적 파일을 프록시 서버가 직접 응답함으로써 백엔드 서버의 응답 필요성을 제거한다. NGINX의 location
디렉티브로 구현 가능하며, CDN과의 조합도 가능하다.
로그인 상태에 영향을 받지 않는 API 응답 등은 캐시 저장 후 일정 시간 동안 동일 응답을 제공할 수 있다. 이는 백엔드 처리 비용을 절감하고 응답 속도를 향상시킨다.
ETag
, Last-Modified
등의 HTTP 헤더 기반 조건부 캐싱을 통해 효율적인 전송 가능.과도한 캐싱은 데이터 불일치를 야기할 수 있으므로 신중한 정책 수립이 요구됨
리버스 프록시는 네트워크 수준에서 접근을 제어하거나 요청의 유효성을 검증하는 보안 기능을 수행할 수 있다.
IP 기반 접근 제한
allow
, deny
지시어 사용.URL/패턴 기반 필터링
/admin
, /shell
, /phpmyadmin
등)에 대한 차단.DDoS 또는 봇 차단 기능
HTTP 인증 처리
NGINX는 경량화된 고성능 HTTP 서버로 출발했지만, 리버스 프록시 기능에서도 매우 널리 활용된다. 낮은 메모리 사용량과 높은 처리 성능, 간단한 설정 방식 덕분에 대규모 서비스에서도 사용된다.
/etc/nginx/sites-available/default
파일에서 location
블록 내에 proxy_pass
지시어를 통해 리버스 프록시를 구성할 수 있다.server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
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_cache
, proxy_buffering
, proxy_redirect
등을 통해 캐싱과 리디렉션 제어 가능listen 443 ssl
및 ssl_certificate
, ssl_certificate_key
설정 추가활용 사례
Apache HTTP Server는 오랜 역사와 광범위한 호환성을 가진 웹 서버이며, mod_proxy
모듈을 활성화하여 리버스 프록시로 사용할 수 있다. 보통 레거시 시스템이나 특정 CMS 기반 시스템에서 많이 활용된다.
a2enmod
명령어를 통해 활성화 가능하다.sudo a2enmod proxy
sudo a2enmod proxy_http
000-default.conf
혹은 별도 VirtualHost 파일 내에 아래와 같이 작성한다.<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
기능 특성
.htaccess
나 다양한 모듈 조합을 통해 세세한 제어가 가능하다는 점에서 유연성이 높다.활용 사례
mod_security
, mod_rewrite
)과의 연계로 보안 정책 적용에 유리HAProxy는 고성능 로드 밸런서이자 리버스 프록시로, 특히 L4(TCP), L7(HTTP) 레벨 모두 지원하는 점이 특징이다. 다수의 연결을 효율적으로 관리할 수 있어 대규모 트래픽 분산에 자주 쓰인다.
/etc/haproxy/haproxy.cfg
파일을 다음과 같이 구성할 수 있다.frontend http_in
bind *:80
default_backend servers
backend servers
balance roundrobin
server web1 192.168.0.101:80 check
server web2 192.168.0.102:80 check
mode tcp
설정 사용.frontend ssl_frontend
bind *:443
mode tcp
default_backend tcp_servers
backend tcp_servers
mode tcp
server ssl1 192.168.0.201:443 check
server ssl2 192.168.0.202:443 check
특징 및 고급 기능
활용 사례
클라우드 인프라에서는 리버스 프록시 역할을 SaaS 형태로 제공하는 서비스들이 존재한다. 인프라 유지 관리 부담이 줄어드는 대신, 구성 방식과 정책 적용은 각 플랫폼에 따라 상이하다.
리버스 프록시는 클라이언트와 실제 서버 사이에 위치하여 트래픽 흐름을 통제하고, 공격을 완화할 수 있는 첫 방어선 역할을 한다. 특히 다음과 같은 보안 기능을 수행한다:
NGINX
의 limit_req
, HAProxy
의 maxconn
옵션 등에서 구현 가능.주의: 프록시 서버 자체가 DDoS 대상이 될 수 있으므로, L3/L4 수준의 방어(방화벽, 클라우드 보안 솔루션 등)와의 병행이 필요함.
리버스 프록시는 WAF(Web Application Firewall)를 프론트에 통합시켜 웹 공격으로부터 백엔드를 보호하는 역할도 수행할 수 있다.
ModSecurity
, AWS WAF
, Cloudflare WAF
등과 연동 가능.주의: WAF는 오탐이 잦을 수 있으므로 예외 규칙 작성과 테스트가 필수적임.
리버스 프록시도 완벽한 보안 장치는 아니며, 구성 방식이나 정책 설정에 따라 우회 공격 및 취약점이 존재할 수 있다.
X-Forwarded-For
, X-Real-IP
등의 헤더에 포함됨./admin
은 차단했지만, /admin/../admin
형태로 우회 가능.location
또는 backend
설정에서 접근 제어 미비 시 발생.주의: 리버스 프록시 설정은 단순히 프록시 역할만 고려할 것이 아니라, 애플리케이션 레이어의 동작과 위협 모델까지 고려해 구성해야 함.
리버스 프록시는 하나의 클라이언트 진입점으로 여러 백엔드 서버 또는 서비스로의 요청을 분배하는 구조를 취한다. 효율적이고 유연한 라우팅 전략은 프록시의 핵심 역할 중 하나이며, 다음과 같은 방식으로 구성할 수 있다:
/api/
→ API 서버, /static/
→ 정적 파일 서버.location
블록으로 쉽게 설정 가능.api.example.com
→ API 서버, www.example.com
→ 웹 서버.weight
설정 지원.주의: 라우팅 전략은 단순한 리다이렉션이 아니라, 백엔드 상태와 트래픽 패턴에 따라 동적으로 조정될 수 있도록 구성해야 함.
리버스 프록시는 백엔드 서버의 정상 동작 여부를 주기적으로 점검하고, 이상 발생 시 자동으로 트래픽을 다른 서버로 우회시킬 수 있어야 한다.
/health
, /ping
등 지정된 엔드포인트에 HTTP 요청을 보내 응답 상태 확인.backup
옵션 사용, NGINX는 별도의 스크립트로 구현 가능.주의: 헬스체크 주기와 타임아웃은 백엔드의 부하와 서비스 특성에 맞게 설정해야 함. 너무 잦거나 너무 느린 체크는 오탐 또는 느린 Failover로 이어질 수 있음.
성능 최적화를 위해 리버스 프록시의 내부 처리 방식과 관련된 여러 요소를 세밀하게 조정해야 한다.
client_body_buffer_size
, proxy_buffer_size
, proxy_buffers
.keepalive_timeout
, keepalive_requests
, keepalive
설정.option http-keep-alive
, timeout client
, timeout server
.Accept-Encoding: gzip
을 보낼 경우 응답 압축 수행.gzip
, gzip_types
, gzip_min_length
설정.sendfile
, tcp_nopush
, tcp_nodelay
옵션 등을 활용해 대용량 파일의 전송 효율을 높임.참고: 무작정 높은 수치를 주는 것이 아닌, 실제 트래픽 특성, 사용 메모리, CPU 활용률 등을 고려해 설정하는 것이 중요함.
리버스 프록시 서버는 트래픽 흐름의 관문이므로 실시간 상태 파악과 문제 대응을 위한 모니터링이 필수이다.
access_log
, error_log
.stub_status
, HAProxy: stats socket
또는 stats page
.팁: 로그는 분석을 위해서만 존재하는 것이 아니라, 이상 징후 감지 및 보안 침해 대응에도 활용되므로 로그 포맷 설계가 매우 중요함.
다양한 플랫폼과 도구에 대해 가장 많이 다뤄야 했던 토픽인 것 같다. 역시 웹 관련 주제인가? 그라파나, 프로메테우스 등 써보고 싶었던 도구들도 얘기가 나오니 반가웠고, 웹서버 관련해서는 프로젝트를 수행하면서 간간이 접했던 내용들도 튀어나와 즐거웠다.