홈/엔지니어/네트워킹 / 서버/Nginx 고급 운영 — 로드밸런싱 · 캐싱 · R…
네트워킹 / 서버고급UbuntuDebianCentOSRHELNginx로드밸런싱캐싱

Nginx 고급 운영 — 로드밸런싱 · 캐싱 · Rate Limiting · 보안 헤더

upstream 로드밸런싱 전략, proxy_cache 콘텐츠 캐싱, limit_req rate limiting, 보안 헤더까지 — 프로덕션 Nginx를 완전히 제어하는 심화 가이드.

목차
  1. 프로덕션 Nginx 설정 구조
  2. 1. upstream 로드밸런싱 전략
  3. 2. proxy_cache — 콘텐츠 캐싱
  4. 3. Rate Limiting — DDoS / 무차별 대입 방어
  5. 4. 보안 헤더 및 SSL 강화
  6. 5. 성능 튜닝 — worker 및 커넥션 최적화

프로덕션 Nginx 설정 구조

단순 리버스 프록시를 넘어, Nginx를 로드밸런서·캐시서버·WAF 전방 배치 레이어로 활용하는 패턴을 다룹니다.


1. upstream 로드밸런싱 전략

기본 구성 (Round Robin)

Nginx
http {
  upstream app_servers {
    least_conn;          # 최소 연결 수 기준 분배 (Round Robin 대신 권장)

    server 10.0.1.10:8080 weight=3;   # 가중치: 트래픽 30%
    server 10.0.1.11:8080 weight=2;
    server 10.0.1.12:8080 weight=1;
    server 10.0.1.13:8080 backup;     # 나머지 전부 다운 시 사용

    keepalive 32;        # upstream keepalive 연결 풀
    keepalive_timeout 60s;
  }

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

    location / {
      proxy_pass http://app_servers;
      proxy_http_version 1.1;
      proxy_set_header Connection "";         # keepalive 유지
      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;
    }
  }
}

세션 지속성 (Sticky Session)

Nginx
upstream app_servers {
  ip_hash;              # 동일 클라이언트 IP는 항상 같은 서버로
  server 10.0.1.10:8080;
  server 10.0.1.11:8080;
}

헬스체크 (Nginx Plus 없이 수동 구현)

Nginx
upstream app_servers {
  server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
  server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
}
# max_fails: 30초 내 3번 실패 시 해당 서버 일시 제외

2. proxy_cache — 콘텐츠 캐싱

Nginx
http {
  # 캐시 저장소 정의 (nginx.conf 최상단 http 블록)
  proxy_cache_path /var/cache/nginx
    levels=1:2                    # 디렉터리 계층 구조
    keys_zone=app_cache:50m       # 메모리 내 키 저장소 50MB
    max_size=10g                  # 최대 디스크 사용량
    inactive=60m                  # 60분간 미접근 시 삭제
    use_temp_path=off;

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

      proxy_cache app_cache;
      proxy_cache_key "$scheme$request_method$host$request_uri";
      proxy_cache_valid 200 302 10m;   # 200/302 응답 10분 캐시
      proxy_cache_valid 404      1m;
      proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
      proxy_cache_lock on;             # 동일 키 중복 요청 방지 (thundering herd)
      proxy_cache_lock_timeout 5s;

      # 캐시 상태 헤더 노출 (디버깅용)
      add_header X-Cache-Status $upstream_cache_status;
    }

    # 캐시 우회: 특정 조건에서
    location /api/user {
      proxy_pass http://app_servers;
      proxy_cache_bypass $cookie_session;  # 세션 쿠키 있으면 캐시 건너뜀
      proxy_no_cache $cookie_session;
    }

    # 캐시 퍼지 (내부에서만 허용)
    location ~ /purge(/.*) {
      allow 127.0.0.1;
      deny all;
      proxy_cache_purge app_cache "$scheme$request_method$host$1";
    }
  }
}
Bash
# 캐시 상태 확인
curl -I https://example.com/static/logo.png | grep X-Cache-Status
# HIT / MISS / BYPASS / UPDATING

# 캐시 디렉터리 크기 확인
du -sh /var/cache/nginx

# 캐시 전체 초기화
sudo rm -rf /var/cache/nginx/*
sudo nginx -s reload

3. Rate Limiting — DDoS / 무차별 대입 방어

Nginx
http {
  # 요청 속도 제한 존 정의
  limit_req_zone $binary_remote_addr zone=api_limit:20m rate=10r/s;
  limit_req_zone $binary_remote_addr zone=login_limit:10m rate=3r/m;
  limit_req_zone $http_x_api_key    zone=key_limit:10m  rate=100r/s;

  # 연결 수 제한 존
  limit_conn_zone $binary_remote_addr zone=conn_limit:20m;

  server {
    # API 엔드포인트: 초당 10req, 버스트 20개 허용
    location /api/ {
      limit_req zone=api_limit burst=20 nodelay;
      limit_conn conn_limit 20;
      limit_req_status 429;

      proxy_pass http://app_servers;
    }

    # 로그인: 분당 3회, 초과 시 큐잉 (nodelay 없음)
    location /auth/login {
      limit_req zone=login_limit burst=5;
      limit_req_status 429;
      proxy_pass http://app_servers;
    }

    # Rate Limit 초과 응답 커스터마이징
    error_page 429 /rate_limit.json;
    location = /rate_limit.json {
      internal;
      default_type application/json;
      return 429 '{"error":"Too Many Requests","retry_after":60}';
    }
  }
}

4. 보안 헤더 및 SSL 강화

Nginx
http {
  # TLS 설정
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;
  ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';

  # HSTS (Strict-Transport-Security)
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

  # DH 파라미터 생성 및 적용
  ssl_dhparam /etc/nginx/dhparam.pem;    # openssl dhparam -out /etc/nginx/dhparam.pem 4096

  # OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4 valid=300s;

  server {
    # 보안 헤더 일괄 설정
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.example.com; img-src 'self' data: cdn.example.com; style-src 'self' 'unsafe-inline';" always;

    # 서버 정보 숨기기
    server_tokens off;

    # HTTP → HTTPS 리다이렉트
    if ($scheme = http) {
      return 301 https://$host$request_uri;
    }
  }
}

5. 성능 튜닝 — worker 및 커넥션 최적화

Nginx
# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;          # CPU 코어 수에 맞게 자동 설정
worker_rlimit_nofile 65535;     # 파일 디스크립터 한도

events {
  worker_connections 4096;      # worker당 최대 연결 수
  use epoll;                    # Linux 최적화 이벤트 방식
  multi_accept on;              # 한 번에 여러 연결 수락
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 65;
  keepalive_requests 1000;

  # Gzip 압축
  gzip on;
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss;
  gzip_min_length 1024;

  # 버퍼 튜닝
  proxy_buffer_size 128k;
  proxy_buffers 4 256k;
  proxy_busy_buffers_size 256k;

  # 타임아웃
  proxy_connect_timeout 5s;
  proxy_send_timeout 60s;
  proxy_read_timeout 60s;
}
Bash
# 설정 검증
sudo nginx -t

# 무중단 설정 리로드
sudo nginx -s reload

# 실시간 연결 통계
sudo nginx -V 2>&1 | grep with-http_stub_status
# status 페이지 확인
curl http://localhost/nginx_status
#Nginx#로드밸런싱#캐싱#rate-limiting#보안헤더#웹서버#성능최적화
편집 안내 · Editorial Note

AI 도구가 초안 작성에 사용될 수 있습니다. 명령어의 실행 여부와 검증 환경은 각 가이드에 기재된 근거를 확인하세요. 적용 전 사용 중인 버전의 공식 문서를 확인하고, 오류는 이메일로 알려주세요. 이메일로 제보

주제 관련 공식 문서(자동 연결 · 문장별 근거 아님)NGINX 공식 문서 ↗OWASP 공식 문서 ↗

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.