NGINX Configuration: Knowledge (NGINX CA, F5N2) 학습 가이드
NGINX Configuration 을 다양한 역할로 구성하는 방법에 대해 정리합니다. 이 글에서는 Load Balancer, 캐시 서버, 웹 서버, 리버스 프록시 구성까지 모두 다룰 예정이며, 실무에서도 바로 적용 가능한 개념과 설정을 중심으로 설명합니다.
목차
1. NGINX Configuration: 로드 밸런서 구성
1-1. 로드 밸런싱 풀 및 알고리즘 이해
1-2. 서버 장애 시 동작 및 제거 처리 방식
1-3. NGINX 로드 밸런서의 특징
1-4. 보안 설정 및 메모리 존 튜닝
1-5. L4 및 API Gateway 구성 방식
2. NGINX Configuration: 캐시 서버 구성
2-1. 캐싱 개념 및 NGINX에서의 필요성
2-2. 캐시 활성화 및 콘텐츠 지정 방법
2-3. 다양한 캐싱 유형 소개
2-4. NGINX 캐시 서버만의 장점
3. NGINX Configuration: 웹 서버 구성
3-1. 정적 vs 동적 콘텐츠 처리
3-2. HTTPS 적용 및 보안 설정
3-3. server, location 블록 구조 이해
4. NGINX Configuration: 리버스 프록시 구성
4-1. 트래픽 라우팅 방식 이해
4-2. 헤더 조작 및 proxy_set_header vs add_header
4-3. 리버스 프록시의 특징과 헬스체크 동작
1. NGINX Configuration: 로드 밸런서 구성
1-1. 로드 밸런싱 풀 및 알고리즘 이해
NGINX에서 로드 밸런싱은 upstream 블록을 통해 백엔드 서버 풀을 정의하고, 다양한 분산 알고리즘(round-robin, least_conn, ip_hash)을 설정할 수 있습니다.
upstream backend {
least_conn;
server app1.example.com;
server app2.example.com weight=2;
server app3.example.com backup;
}
- Round-robin (기본값): 요청을 순차적으로 각 서버에 분배합니다.
- Least Connections (
least_conn): 현재 활성 연결 수가 가장 적은 서버로 요청을 라우팅합니다. - IP Hash (
ip_hash): 클라이언트 IP 주소를 해싱하여 특정 서버에 고정 배정합니다. 세션 지속성이 필요한 경우 유용합니다. - Generic Hash (
hash $request_uri consistent, NGINX Plus에서 더 다양한 옵션): 지정된 키 값(URL, 쿠키 등)으로 해시 분배를 수행합니다. - Least Time (
least_time, NGINX Plus 전용): 응답 시간과 연결 수를 모두 고려하여 최적의 서버를 선택합니다.
서버 풀을 정의한 후에는 proxy_pass 지시어를 사용하여 실제 트래픽을 전달합니다.
location / {
proxy_pass http://backend;
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;
}
1-2. 서버 장애 시 동작 및 제거 처리 방식
서버가 다운되면 NGINX는 기본적으로 해당 서버에 대한 요청을 중단하지 않습니다. 따라서 max_fails, fail_timeout 설정으로 장애 서버를 자동 제외시킬 수 있습니다.
upstream backend {
server app1.example.com max_fails=3 fail_timeout=30s;
server app2.example.com max_fails=3 fail_timeout=30s;
server backup.example.com backup;
}
- max_fails: 이 값만큼 연속 실패 시 서버를 비활성화합니다 (기본값: 1).
- fail_timeout: 서버가 실패 상태로 간주되는 시간과 비활성화 기간을 정의합니다 (기본값: 10초).
- backup: 기본 서버가 모두 사용 불가능할 때만 요청을 처리하는 백업 서버를 지정합니다.
- down: 서버를 영구적으로 비활성화합니다 (수동 관리용).
1-3. NGINX 로드 밸런서의 특징
NGINX는 아래와 같은 특성으로 고성능 로드 밸런서로 널리 사용됩니다.
- 비동기 이벤트 기반 처리: 수천 개의 동시 연결을 적은 리소스로 처리 가능
- 가벼운 구조: 무거운 WAS 대신 간편한 분산 트래픽 처리에 최적
- 정적 리소스 + 로드 밸런싱 통합 운영 가능: 웹 서버 + LB 역할을 동시에 수행 가능
- 내장 캐시 기능과 연계 가능: 응답 속도 향상 및 백엔드 부하 분산
1-4. 보안 설정 및 메모리 존 튜닝
로드 밸런싱 환경에서는 보안과 성능 최적화가 중요합니다. SSL/TLS 구성과 메모리 존 튜닝을 통해 안전하고 효율적인 로드 밸런서를 구축할 수 있습니다.
# 공유 메모리 존 설정
http {
# 캐시 메모리 존 설정
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=60m max_size=1g;
# 업스트림 서버 상태 추적을 위한 메모리 존
upstream backend {
zone backend 64k;
server app1.example.com;
server app2.example.com;
}
# 연결 제한을 위한 메모리 존
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
listen 443 ssl http2;
# SSL 설정
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS 설정
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}
}
- Zone 설정: 공유 메모리 영역을 할당하여 워커 프로세스 간 데이터 공유 및 빠른 참조 가능
- TLS 최적화: 현대적인 암호화 스위트와 TLS 1.3 지원으로 보안 강화 및 성능 향상
- 세션 캐싱: SSL 세션 재사용을 통한 핸드셰이크 오버헤드 감소
1-5. L4 및 API Gateway 구성 방식
L4 로드 밸런서 (TCP/UDP 트래픽)
NGINX는 stream 모듈을 통해 L4 로드 밸런싱을 제공합니다. 이를 통해 HTTP 외에도 DB, 메일, 게임 서버 등의 TCP/UDP 기반 서비스 부하 분산이 가능합니다.
stream {
upstream mysql_cluster {
hash $remote_addr consistent;
server 10.0.0.1:3306 weight=5;
server 10.0.0.2:3306 max_fails=2 fail_timeout=30s;
server 10.0.0.3:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_cluster;
proxy_connect_timeout 3s;
proxy_timeout 10s;
}
upstream redis_servers {
server 10.0.0.10:6379;
server 10.0.0.11:6379;
}
server {
listen 6379;
proxy_pass redis_servers;
}
}
API Gateway 구성
NGINX는 다양한 API 게이트웨이 기능을 제공하여 마이크로서비스 아키텍처의 진입점 역할을 할 수 있습니다.
http {
# JWT 인증 설정 (NGINX Plus 기능)
auth_jwt "API Gateway";
auth_jwt_key_file /etc/nginx/jwt_keys/public.pem;
# 다양한 백엔드 서비스 정의
upstream auth_service {
server auth.internal:8080;
}
upstream users_service {
server users.internal:8080;
}
upstream products_service {
server products.internal:8080;
}
server {
listen 443 ssl http2;
# 인증 서비스 라우팅
location /auth/ {
proxy_pass http://auth_service;
# JWT 인증 생략 (인증 서비스 자체이므로)
auth_jwt off;
}
# 사용자 API 라우팅
location /api/users/ {
proxy_pass http://users_service;
# 속도 제한 적용
limit_req zone=api_limit burst=20;
}
# 상품 API 라우팅
location /api/products/ {
proxy_pass http://products_service;
# 캐싱 적용
proxy_cache API_CACHE;
proxy_cache_valid 200 5m;
}
# API 문서 서비스
location /docs/ {
root /var/www/api-docs;
index index.html;
}
# Prometheus 메트릭 엔드포인트 (NGINX Plus)
location /api/metrics {
api;
allow 10.0.0.0/8;
deny all;
}
}
}
API Gateway로서 NGINX는 다음과 같은 기능을 제공합니다.
- 요청 라우팅 및 분배
- 인증 및 권한 관리 (JWT, OAuth 등)
- 속도 제한 및 사용량 제어
- 요청/응답 변환 및 조작
- 모니터링 및 로깅
- Caching 및 압축
2. NGINX Configuration: 캐시 서버 구성
2-1. 캐싱 개념 및 NGINX에서의 필요성
NGINX 캐싱 시스템은 백엔드 서버의 부하를 줄이고 응답 시간을 향상시키는 강력한 기능입니다.
캐싱이 필요한 이유
- 성능 최적화: 백엔드 서버 처리 없이 빠른 응답 제공
- 부하 감소: 백엔드 서버 요청 횟수 감소로 리소스 절약
- 확장성 향상: 동일 인프라로 더 많은 요청 처리 가능
- 가용성 증대: 백엔드 서버 장애 시에도 캐시된 콘텐츠 제공 가능
- 비용 절감: 대역폭 및 컴퓨팅 자원 사용 효율화
2-2. 캐시 활성화 및 콘텐츠 지정 방법
NGINX 캐싱 시스템은 유연하고 세밀한 제어가 가능하며, 다양한 시나리오에 맞게 조정할 수 있습니다.
http {
# 캐시 스토리지 정의
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m
inactive=24h max_size=1g use_temp_path=off;
server {
listen 80;
# 정적 콘텐츠 캐싱
location /static/ {
proxy_cache STATIC;
proxy_cache_valid 200 302 304 1d;
proxy_cache_valid 404 1m;
proxy_cache_key $scheme$request_method$host$request_uri;
proxy_pass http://backend;
# 캐시 상태를 응답 헤더에 포함
add_header X-Cache-Status $upstream_cache_status;
# 캐시 우회 조건
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_pragma;
}
# API 응답 캐싱
location /api/ {
proxy_cache API_CACHE;
proxy_cache_valid 200 5m;
# 쿼리 파라미터를 포함한 캐시 키
proxy_cache_key $scheme$host$request_uri;
# 헤더 기반 캐시 제어
proxy_cache_bypass $http_cache_bypass;
proxy_pass http://api_backend;
}
}
}
주요 캐싱 지시어 설명
- proxy_cache_path: 캐시 저장 경로, 디렉토리 레벨, 메모리 존, 최대 크기 등 정의
levels: 캐시 파일 디렉토리 계층 구조 정의 (성능 최적화)keys_zone: 캐시 키와 메타데이터를 저장할 메모리 영역 이름과 크기inactive: 지정 기간 동안 접근되지 않은 항목 삭제 (기본값: 10분)max_size: 캐시 최대 크기 (초과 시 LRU 알고리즘으로 오래된 항목 제거)use_temp_path: 임시 파일 사용 여부 (off 권장)
- proxy_cache: 사용할 캐시 존 지정
- proxy_cache_valid: HTTP 상태 코드별 캐시 유효 기간 설정
- proxy_cache_key: 캐시 키 생성 규칙 (URL, 쿠키, 헤더 등 조합 가능)
- proxy_cache_bypass: 캐시를 우회하는 조건 정의
- proxy_no_cache: 캐싱하지 않을 조건 정의
2-3. 다양한 캐싱 유형 소개
NGINX는 다양한 캐싱 전략을 구현할 수 있습니다.
정적 콘텐츠 캐싱
이미지, CSS, JavaScript, 폰트 등의 정적 리소스를 장시간 캐싱하여 서버 부하 감소
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_cache STATIC;
proxy_cache_valid 200 30d;
proxy_ignore_headers Cache-Control;
add_header Cache-Control "public, max-age=2592000";
proxy_pass http://backend;
}
동적 콘텐츠 캐싱
API 응답이나 동적으로 생성된 HTML을 적절한 시간 동안 캐싱
location /api/products/ {
proxy_cache API_CACHE;
proxy_cache_valid 200 10m;
proxy_cache_methods GET HEAD;
proxy_cache_key $host$request_uri$cookie_user;
proxy_pass http://backend;
}
마이크로 캐싱
극도로 짧은 시간(수 초) 동안 캐싱하여 트래픽 폭주 시 서버 보호
location / {
proxy_cache MICROCACHE;
proxy_cache_valid 200 1s;
proxy_cache_lock on;
proxy_cache_use_stale updating;
proxy_pass http://dynamic_backend;
}
스탈 캐싱(Stale Cache)
백엔드 서버 장애 시 만료된 캐시 콘텐츠를 제공하여 가용성 보장
location /api/ {
proxy_cache API_CACHE;
proxy_cache_valid 200 5m;
# 오류 발생 시 30분까지 만료된 캐시 사용
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504 http_429 http_403 http_404 http_429 60m;
proxy_pass http://backend;
}
조건부 캐싱
특정 조건(예: 인증된 사용자, 특정 헤더 값)에 따른 선택적 캐싱
location /api/user/ {
set $no_cache "";
# 로그인 사용자는 캐싱하지 않음
if ($http_authorization ~* "^Bearer") {
set $no_cache 1;
}
proxy_cache API_CACHE;
proxy_cache_valid 200 5m;
proxy_no_cache $no_cache;
proxy_cache_bypass $no_cache;
proxy_pass http://backend;
}
2-4. NGINX Cache Server만의 장점
NGINX 캐싱 시스템은 다른 솔루션에 비해 여러 장점을 제공합니다:
- 통합 솔루션: 별도의 캐시 서버 없이 웹 서버와 리버스 프록시 기능에 캐싱 통합
- 메모리와 디스크 조합: 메타데이터는 메모리에, 콘텐츠는 디스크에 저장하여 빠른 조회와 대용량 저장 모두 실현
- 세분화된 제어: URL, 헤더, 쿠키, 요청 메소드 등 다양한 조건으로 캐싱 정책 설정 가능
- 동적 캐시 제어: 백엔드 응답 헤더(Cache-Control, Expires)를 존중하거나 재정의 가능
- 캐시 퍼지(NGINX Plus): 특정 캐시 항목을 동적으로 갱신하거나 제거 가능
- 멀티 레이어 캐싱: 브라우저 캐시, NGINX 캐시, 백엔드 캐시를 계층적으로 구성 가능
- 분산 캐싱: 여러 NGINX 인스턴스에 캐시를 분산하여 고가용성 실현
- 캐시 락: 동일 리소스에 대한 중복 요청 방지로 백엔드 부하 감소 (
proxy_cache_lock)
3. NGINX Configuration: 웹 서버 구성
3-1. 정적 vs 동적 콘텐츠 처리
NGINX는 효율적인 정적 파일 서빙과 동적 콘텐츠 프록시를 모두 지원합니다.
server {
listen 80;
server_name example.com;
root /var/www/html;
# 정적 콘텐츠 직접 서빙
location /static/ {
alias /var/www/static/;
expires 30d;
access_log off;
add_header Cache-Control "public, max-age=2592000";
}
# 이미지, CSS, JS 파일 처리
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public";
}
# PHP 처리를 위한 FastCGI 프록시
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
}
# Node.js 애플리케이션으로 프록시
location /app/ {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 기본 정적 파일 처리
location / {
try_files $uri $uri/ /index.html;
}
}
고급 라우팅 기법
NGINX는 강력한 정규표현식과 변수를 통해 복잡한 라우팅 로직을 구현할 수 있습니다.
# 정확한 문자열 매칭 (= 접두사)
location = /exact/path {
# 정확히 /exact/path와 일치하는 요청만 처리
}
# 대소문자 구분 없는 정규표현식 매칭 (~*)
location ~* \.(png|jpg|jpeg)$ {
# 이미지 파일 처리
}
# 우선순위가 낮은 접두사 매칭 (^~)
location ^~ /important/prefix {
# /important/prefix로 시작하는 모든 요청과 매칭
# 정규표현식보다 우선
}
# 중첩 위치 블록
location /api/ {
# /api/ 내 특정 엔드포인트에 대한 추가 라우팅
location ~ ^/api/v2/ {
# /api/v2/ 경로 처리
}
}
# 조건부 라우팅
location / {
if ($request_method = POST) {
return 307 https://api.example.com$request_uri;
}
# 모바일 기기에 대한 특수 처리
if ($http_user_agent ~* "mobile") {
proxy_pass http://mobile_backend;
}
}
3-2. HTTPS 적용 및 보안 설정
현대 웹 환경에서는 HTTPS 적용과 보안 강화가 필수적입니다. NGINX에서는 다양한 보안 설정을 통해 안전한 웹 서버를 구성할 수 있습니다.
server {
listen 443 ssl http2;
server_name example.com;
# SSL 인증서 설정
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
# 현대적인 TLS 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
# SSL 세션 캐시 설정
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# 보안 헤더 추가
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; img-src 'self' data: https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none'" always;
# HTTP/2 설정
http2_push_preload on;
# TLS 1.0/1.1 리다이렉트 (레거시 브라우저 지원 시)
if ($ssl_protocol = "") {
return 301 https://$host$request_uri;
}
# 기타 설정...
}
# HTTP에서 HTTPS로 리다이렉트
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
주요 보안 설정 설명
- TLS 1.2/1.3: 안전한 최신 암호화 프로토콜만 활성화
- 강력한 암호화 스위트: 보안이 강화된 암호화 알고리즘 설정
- HSTS (HTTP Strict Transport Security): 브라우저가 항상 HTTPS 사용하도록 지시
- OCSP Stapling: SSL 인증서 유효성 검증 개선
- CSP (Content Security Policy): XSS 공격 방지를 위한 리소스 로드 제한
- X-Frame-Options: 클릭재킹 공격 방지
- X-XSS-Protection: 브라우저의 XSS 필터 활성화
- X-Content-Type-Options: MIME 스니핑 방지
3-3. server, location 블록 구조 이해
NGINX 구성의 핵심은 계층적인 블록 구조입니다. server 블록은 가상 호스트를 정의하고, location 블록은 URI 패턴별 처리 로직을 정의합니다.
server 블록
server 블록은 도메인과 포트를 기반으로 요청을 가상 서버로 라우팅합니다.
# 기본 HTTP 서버
server {
listen 80 default_server;
server_name _;
# 기본 서버 설정...
}
# 특정 도메인 서버
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 도메인별 설정...
}
# 특정 IP 및 포트 바인딩
server {
listen 192.168.1.10:8080;
server_name internal.example.com;
# 내부용 서버 설정...
}
server_name 지시어는 다음과 같은 패턴을 지원합니다:
- 정확한 이름 매칭:
example.com - 와일드카드 매칭:
*.example.com,example.* - 정규표현식 매칭:
~^www\d+\.example\.com$ - 복수 도메인:
example.com www.example.com shop.example.com
location 블록
location 블록은 URI 경로를 기반으로 요청 처리 로직을 정의합니다.
server {
# 기본 location 블록
location / {
# 기본 처리 로직
}
# 정확한 경로 매칭
location = /exact {
# /exact와 정확히 일치하는 요청만 처리
}
# 접두사 매칭 (우선순위 증가)
location ^~ /images/ {
# /images/로 시작하는 모든 요청
# 정규표현식보다 우선 처리
}
# 대소문자 구분 정규표현식
location ~ \.php$ {
# .php로 끝나는 모든 요청
}
# 대소문자 구분 없는 정규표현식
location ~* \.(jpe?g|png|gif)$ {
# 이미지 파일 처리
}
}
NGINX는 다음 순서로 location 블록을 평가합니다:
- 정확한 매칭(
=) – 가장 높은 우선순위 - 접두사 매칭 중 ^~ 지정된 것 – 가장 긴 매칭이 우선함
- 정규표현식 매칭(
~,~*) – 구성 파일에 나타나는 순서대로 - 일반 접두사 매칭 – 가장 긴 매칭이 우선함
이 우선순위를 이해하면 URL 라우팅을 정밀하게 제어할 수 있습니다.
4. NGINX Configuration: 리버스 프록시 구성
4-1. 트래픽 라우팅 방식 이해
리버스 프록시는 클라이언트 요청을 백엔드 서버로 전달하고 응답을 클라이언트에 반환하는 중개자 역할을 합니다. NGINX는 강력한 리버스 프록시 기능을 제공합니다.
server {
listen 80;
server_name api.example.com;
# 기본 프록시 설정
location / {
proxy_pass http://backend_servers;
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;
}
# 경로 기반 라우팅
location /users/ {
proxy_pass http://user_service;
}
location /products/ {
proxy_pass http://product_service;
}
# 경로 재작성 (URI 변경)
location /api/v1/ {
# /api/v1/users가 backend에서는 /users로 처리됨
proxy_pass http://backend/;
}
# 조건부 라우팅
location /app/ {
# 브라우저 기반 분기 처리
if ($http_user_agent ~* "Chrome") {
proxy_pass http://chrome_optimized;
}
# 기본 백엔드
proxy_pass http://backend;
}
# 복잡한 URL 조작
location ~ ^/legacy/(.*)$ {
# /legacy/path를 /new/path로 변환
proxy_pass http://backend/new/$1;
}
}
주요 프록시 지시어
- proxy_pass: 요청을 전달할 백엔드 서버 또는 업스트림 지정
- proxy_set_header: 백엔드로 전달할 HTTP 헤더 설정
- proxy_redirect: 백엔드 서버에서 반환된 리다이렉트 응답의 Location 헤더 재작성
- proxy_read_timeout: 백엔드 서버에서 응답을 읽는 시간 제한
- proxy_connect_timeout: 백엔드 서버 연결 시간 제한
- proxy_buffer_size, proxy_buffers: 응답 버퍼링 설정
- proxy_next_upstream: 실패 시 다음 업스트림 서버로 요청 전달 조건
4-2. 헤더 조작 및 proxy_set_header vs add_header
NGINX에서 헤더 조작은 리버스 프록시 구성의 중요한 부분입니다. proxy_set_header와 add_header는 서로 다른 용도로 사용됩니다.
server {
# 백엔드로 전달할 요청 헤더 설정
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 사용자 정의 헤더 추가
proxy_set_header X-Request-ID $request_id;
proxy_set_header Authorization ""; # 특정 헤더 제거
location /api/ {
# 클라이언트에게 전달할 응답 헤더 설정
add_header X-Powered-By "NGINX";
add_header X-Cache-Status $upstream_cache_status;
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
# 보안 관련 헤더
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
proxy_pass http://backend;
}
# 헤더 상속 주의사항
location /nested/ {
# add_header는 상속되지만, 하위 블록에서 add_header가 있으면 상속 끊김
add_header X-Parent "Value";
location /nested/child/ {
# 이 블록에서 add_header가 하나라도 있으면 부모의 add_header 상속 안됨
add_header X-Child "Value";
# X-Parent는 여기서 출력되지 않음
}
}
}
proxy_set_header vs add_header
- proxy_set_header:
- 백엔드 서버로 보내는 요청 헤더 설정
- 클라이언트 정보(IP, 프로토콜 등) 전달에 필수
- 빈 값 설정 시 해당 헤더 제거
- 부모 블록에서 설정된 값이 하위 블록으로 상속됨
- add_header:
- 클라이언트에게 보내는 응답 헤더 설정
- CORS, 보안 정책, 캐시 정보 등 전달에 사용
- 특정 응답 코드에만 적용 가능 (기본: 200, 201, 204, 206, 301, 302, 303, 304, 307, 308)
always파라미터 사용 시 모든 응답 코드에 적용- 같은 헤더가 여러 번 정의되면 모두 출력됨
- 상속 시 주의: 하위 블록에서 add_header 사용 시 부모의 add_header가 모두 무시됨
4-3. 리버스 프록시의 특징과 헬스체크 동작
리버스 프록시로서 NGINX는 백엔드 서비스의 가용성과 성능을 관리하는 중요한 역할을 합니다.
NGINX OSS의 패시브 헬스체크
오픈 소스 NGINX는 기본적으로 패시브 헬스체크를 제공합니다:
upstream backend {
server app1.example.com max_fails=3 fail_timeout=30s;
server app2.example.com max_fails=3 fail_timeout=30s;
server backup.example.com backup;
}
- max_fails: 서버가 실패로 간주되기 위한 연속 실패 횟수
- fail_timeout: 두 가지 용도로 사용됨
- 실패 판정을 위한 시간 간격
- 실패 후 서버가 비활성화되는 시간
- passive monitoring: 실제 클라이언트 요청에 대한 응답을 모니터링하여 서버 상태 판단
NGINX Plus의 액티브 헬스체크
NGINX Plus는 더 강력한 액티브 헬스체크 기능을 제공합니다:
upstream backend {
zone backend 64k;
server app1.example.com:8080;
server app2.example.com:8080;
# 액티브 헬스체크 설정
health_check uri=/health interval=5s jitter=3s fails=3 passes=2;
}
# 상세 헬스체크 설정
location /api/ {
proxy_pass http://backend;
health_check match=api_health;
}
# 매치 조건 정의
match api_health {
status 200-399;
header Content-Type = application/json;
body ~ '"status":"UP"';
}
- health_check: 정기적으로 백엔드 서버에 요청을 보내 상태 확인
- interval: 헬스체크 요청 간격
- jitter: 헬스체크 타이밍 변동 범위 (DDoS 방지)
- fails/passes: 상태 전환을 위한 연속 실패/성공 횟수
- match: 성공 판정을 위한 응답 조건 (상태 코드, 헤더, 본문 등)
리버스 프록시의 주요 특징
- 트래픽 제어
- 속도 제한, 연결 제한으로 DDoS 방어 및 리소스 보호
- 우선순위에 따른 트래픽 분배 및 제어
- SSL Termination 처리
- 클라이언트-프록시 구간만 암호화하여 백엔드 리소스 절약
- 중앙화된 인증서 관리로 운영 효율성 향상
- 요청/응답 변환
- URL 재작성으로 내부 구조 변경 시 클라이언트 영향 최소화
- 응답 압축, 최소화로 성능 향상
- 고급 라우팅
- 콘텐츠 기반 라우팅으로 마이크로서비스 아키텍처 지원
- A/B 테스트, 블루-그린 배포 지원
- 보안 강화
- WAF(Web Application Firewall) 기능 제공
- 요청 필터링 및 검증
- 중앙화된 인증/인가 적용
- 로깅 및 모니터링
- 모든 요청에 대한 중앙화된 로깅
- 응답 시간, 오류율 등 주요 지표 수집
5. 결론
이 글에서는 NGINX의 네 가지 주요 기능인 로드 밸런서, 캐시 서버, 웹 서버, 리버스 프록시로서의 구성 방법을 상세히 살펴보았습니다. NGINX는 이러한 역할을 단일 소프트웨어로 통합하여 제공함으로써 효율적인 웹 인프라 구축을 가능하게 합니다.
중요한 점은 이러한 기능들이 서로 독립적이지 않고 상호 보완적으로 작동한다는 것입니다. 예를 들어, 리버스 프록시로 구성된 NGINX는 동시에 로드 밸런싱과 캐싱 기능을 제공할 수 있습니다. 이러한 유연성과 확장성이 NGINX를 현대 웹 아키텍처의 핵심 구성 요소로 만들었습니다.
NGINX CA에 대한 다양한 학습가이드는 아래에서 확인할 수 있습니다.
1. NGINX Management (NGINX CA, F5N1) 학습 가이드
2. NGINX Configuration: Knowledge (NGINX CA, F5N2) 학습 가이드
3. NGINX Configuration: Demonstrate (NGINX CA, F5N3) 학습 가이드
4. NGINX Troubleshoot (NGINX CA, F5N4) 학습 가이드