2 분 소요

리버스 프록시는 클라이언트와 백엔드 서버 사이에서 요청을 중계하는 서버입니다. Nginx를 리버스 프록시로 활용하면 SSL 처리, 정적 파일 캐싱, 압축, 보안 헤더 추가 등의 기능을 백엔드에서 분리하여 처리할 수 있습니다.

보안 이미지

Nginx 리버스 프록시로 구성된 웹 서비스 아키텍처

기본 리버스 프록시 설정

# /etc/nginx/conf.d/proxy.conf

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_set_header X-Forwarded-Proto $scheme;
    }
}

SSL 종료(Termination) 설정

server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL 인증서
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL 보안 설정
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # 보안 헤더
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header Referrer-Policy "strict-origin-when-cross-origin";

    location / {
        proxy_pass http://127.0.0.1:3000;
        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 https;
    }
}

# HTTP → HTTPS 리다이렉트
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

경로 기반 프록시 (API 게이트웨이)

server {
    listen 443 ssl;
    server_name api.example.com;

    # 정적 파일
    location /static/ {
        root /var/www;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # REST API → Node.js
    location /api/v1/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_read_timeout 30s;
    }

    # WebSocket → Node.js
    location /ws/ {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # 파일 업로드 → Python 서비스
    location /upload/ {
        proxy_pass http://127.0.0.1:5000;
        client_max_body_size 100M;
        proxy_read_timeout 300s;
    }
}

프록시 캐싱 설정

# /etc/nginx/nginx.conf (http 블록 내)
proxy_cache_path /var/cache/nginx
    levels=1:2
    keys_zone=my_cache:10m
    max_size=10g
    inactive=60m
    use_temp_path=off;

# /etc/nginx/conf.d/proxy.conf
server {
    location / {
        proxy_pass http://backend;
        proxy_cache my_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout http_500 http_502 http_503;
        proxy_cache_lock on;

        # 캐시 상태를 응답 헤더에 추가 (디버깅)
        add_header X-Cache-Status $upstream_cache_status;
    }

    # 캐시 무효화 (특정 IP에서만 허용)
    location ~ /purge(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge my_cache $scheme$host$1;
    }
}

데이터 서버 이미지

리버스 프록시를 통한 트래픽 흐름 모니터링

속도 제한(Rate Limiting)

# 요청 속도 제한 존 정의 (http 블록)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;

server {
    # API 엔드포인트 속도 제한
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;
        limit_req_status 429;
        proxy_pass http://backend;
    }

    # 로그인 엔드포인트 엄격한 제한
    location /api/auth/login {
        limit_req zone=login_limit burst=5;
        proxy_pass http://backend;
    }
}

타임아웃 설정

server {
    location / {
        proxy_pass http://backend;

        # 연결 타임아웃 (백엔드 연결 시도 최대 시간)
        proxy_connect_timeout 5s;

        # 쓰기 타임아웃 (백엔드로 요청 전송 최대 시간)
        proxy_send_timeout 60s;

        # 읽기 타임아웃 (백엔드 응답 대기 최대 시간)
        proxy_read_timeout 60s;

        # 긴 작업용 별도 location
    }

    location /api/export {
        proxy_pass http://backend;
        proxy_read_timeout 300s;  # 5분
        proxy_send_timeout 300s;
    }
}

업스트림 헬스체크

# Nginx Plus 또는 nginx_upstream_check_module 사용
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;

    keepalive 32;
}

server {
    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
    }
}

설정 적용 및 테스트

# 설정 문법 검사
nginx -t

# 설정 리로드 (무중단)
systemctl reload nginx

# 프록시 동작 확인
curl -I https://example.com/api/health
curl -v http://127.0.0.1:8080  # 백엔드 직접 확인

# 캐시 상태 확인
curl -I https://example.com/api/data | grep X-Cache-Status

# 속도 제한 테스트
for i in {1..20}; do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/api/test; done

Nginx 리버스 프록시는 단순 중계 기능을 넘어 SSL 처리, 캐싱, 속도 제한, 보안 헤더 주입 등 다양한 미들웨어 역할을 합니다. 백엔드 애플리케이션이 비즈니스 로직에만 집중할 수 있도록 인프라 관심사를 Nginx에서 처리하는 아키텍처를 권장합니다.

댓글남기기