[Nginx] Nginx 종합 설정 가이드: 기초부터 고급 최적화까지




Nginx는 단순한 웹 서버를 넘어 현대 웹 인프라의 핵심 구성 요소로 자리잡았습니다. 본 가이드는 실제 구축 순서에 따라 필수 기본 설정부터 고급 최적화까지 단계적으로 진행하여, 실무에서 바로 적용할 수 있는 체계적인 Nginx 설정 방법을 제시합니다.

1단계: 기본 구조 설계 및 필수 설정

디렉토리 구조 설계

Nginx 설정의 첫 번째 단계는 체계적인 파일 구조를 설계하는 것입니다:

/etc/nginx/
├── nginx.conf                      # 메인 설정 파일 (가장 중요)
├── conf.d/                         # 사이트별 설정
├── snippets/                       # 재사용 가능한 설정 조각
├── upstream/                       # 백엔드 서버 정의
├── security/                       # 보안 설정
├── performance/                    # 성능 최적화
├── monitoring/                     # 로깅 & 모니터링
└── scripts/                        # 관리 스크립트

핵심 메인 설정 (nginx.conf)

모든 Nginx 설정의 기초가 되는 메인 설정파일부터 시작합니다. 단계별로 필요한 설정들을 import하는 구조로 구성합니다:

# nginx.conf - 단계별 설정 import 구조
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 기본 보안 설정
worker_rlimit_nofile 65535;

events {
    worker_connections 1024;        # 기본값, 나중에 최적화
    use epoll;
    multi_accept on;
}

http {
    # 1단계: 기본 필수 설정
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # 2단계: 로그 형식 정의 (기본 → 확장)
    include /etc/nginx/monitoring/log-formats.conf;
    
    # 3단계: 맵 정의들 (조건부 처리용)
    include /etc/nginx/maps/*.conf;
    
    # 4단계: 기본 성능 설정
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    # 5단계: 성능 최적화 설정 (단계적 적용)
    include /etc/nginx/performance/compression.conf;
    include /etc/nginx/performance/file-cache.conf;
    # include /etc/nginx/performance/optimization.conf;  # 6단계에서 주석 해제
    
    # 6단계: 보안 설정 (기본 → 고급)
    server_tokens off;
    include /etc/nginx/security/basic-headers.conf;
    include /etc/nginx/security/basic-access.conf;
    # include /etc/nginx/security/rate-limiting.conf;   # 7단계에서 주석 해제
    # include /etc/nginx/security/csp.conf;             # 7단계에서 주석 해제
    
    # 7단계: 업스트림 서버 정의 (백엔드 연동 시)
    include /etc/nginx/upstream/*.conf;
    
    # 8단계: 캐싱 설정 (필요 시)
    # include /etc/nginx/performance/proxy-cache.conf;  # 9단계에서 주석 해제
    
    # 9단계: 모니터링 설정
    # include /etc/nginx/monitoring/status.conf;        # 운영 시 주석 해제
    
    # 최종: 사이트별 설정 로드 (항상 마지막)
    include /etc/nginx/conf.d/*.conf;
}

첫 번째 가상 호스트 설정

기본적인 사이트 설정으로 시작합니다:

# conf.d/example.com.conf - 기본 사이트 설정
server {
    listen 80;
    server_name example.com www.example.com;
    
    # 기본 보안 설정
    client_max_body_size 10M;
    
    # 문서 루트
    root /var/www/example.com;
    index index.html index.htm;
    
    # 기본 로깅
    access_log /var/log/nginx/example.com.access.log main;
    error_log /var/log/nginx/example.com.error.log;
    
    # 기본 위치 블록
    location / {
        try_files $uri $uri/ =404;
    }
    
    # 정적 파일 기본 캐싱
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1d;
        add_header Cache-Control "public";
    }
}

2단계: 필수 보안 설정 적용

기본 구조가 완성되면 보안 설정을 적용합니다.

기본 보안 헤더 설정

# security/basic-headers.conf
# 기본적으로 모든 사이트에 적용할 보안 헤더

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# 서버 정보 숨김
server_tokens off;

기본 접근 제어

# security/basic-access.conf
# 위험한 파일들에 대한 기본 접근 차단

# 숨김 파일 차단
location ~ /\. {
    deny all;
    access_log off;
}

# 백업 파일 차단
location ~* \.(bak|backup|old|tmp)$ {
    deny all;
}

메인 설정에 보안 설정 포함

# nginx.conf에 추가
http {
    # ... 기존 설정들 ...
    
    # 기본 보안 설정 포함
    include /etc/nginx/security/basic-headers.conf;
    include /etc/nginx/security/basic-access.conf;
    
    # ... 나머지 설정들 ...
}

3단계: SSL/HTTPS 설정 (필수)

현재 모든 웹사이트는 HTTPS가 필수이므로 SSL 설정을 진행합니다.

기본 SSL 설정

# snippets/ssl-params.conf
# 재사용 가능한 SSL 설정

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;

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;

HTTPS 사이트 설정으로 업그레이드

# conf.d/example.com.conf - HTTPS로 업그레이드
server {
    listen 80;
    server_name example.com www.example.com;
    
    # HTTPS로 리디렉션
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL 인증서
    ssl_certificate /etc/nginx/certs/example.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/example.com/privkey.pem;
    
    # SSL 설정 포함
    include /etc/nginx/snippets/ssl-params.conf;
    
    # HSTS 헤더 추가
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # 기존 설정들...
    root /var/www/example.com;
    index index.html index.htm;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

4단계: 백엔드 연동 (업스트림 설정)

정적 사이트에서 동적 애플리케이션으로 발전시킬 때 업스트림을 설정합니다.

기본 업스트림 정의

# upstream/backend-servers.conf
# 백엔드 서버 그룹 정의

upstream app_backend {
    server 127.0.0.1:3000;  # 단일 서버로 시작
    keepalive 32;
}

프록시 설정 추가

# snippets/proxy-params.conf
# 기본 프록시 설정

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_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;

사이트 설정에 프록시 적용

# conf.d/example.com.conf에 추가
server {
    # ... SSL 설정들 ...
    
    # 정적 파일은 직접 제공
    location /static/ {
        root /var/www/example.com;
        expires 1M;
    }
    
    # 동적 요청은 백엔드로 프록시
    location / {
        proxy_pass http://app_backend;
        include /etc/nginx/snippets/proxy-params.conf;
    }
}

5단계: 기본 성능 최적화

기본 기능이 동작하면 성능 최적화를 진행합니다.

워커 프로세스 최적화

# nginx.conf 업데이트
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;  # 기본 1024에서 증가
    use epoll;
    multi_accept on;
    accept_mutex off;
}

기본 압축 설정

# performance/compression.conf
# 기본 Gzip 압축

gzip on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
    text/plain
    text/css
    application/json
    application/javascript
    text/xml
    application/xml;

파일 캐시 최적화

# performance/file-cache.conf
# 파일 디스크립터 캐시

open_file_cache max=10000 inactive=60s;
open_file_cache_valid 120s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

6단계: 로깅 및 모니터링 구성

운영을 위한 로깅과 모니터링을 설정합니다.

확장된 로그 형식

# monitoring/log-formats.conf
log_format main_extended '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'rt=$request_time uct="$upstream_connect_time" '
                        'urt="$upstream_response_time"';

상태 모니터링

# monitoring/status.conf
location /nginx_status {
    stub_status;
    allow 127.0.0.1;
    allow 10.0.0.0/8;
    deny all;
    access_log off;
}

7단계: 고급 보안 설정

기본 운영이 안정되면 고급 보안 기능을 추가합니다.

Rate Limiting 구현

# security/rate-limiting.conf
# DDoS 및 브루트포스 공격 방어

limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

# 사이트 설정에 적용
location / {
    limit_req zone=general burst=20 nodelay;
    proxy_pass http://app_backend;
}

location /login {
    limit_req zone=login burst=5 nodelay;
    proxy_pass http://app_backend;
}

Content Security Policy

# security/csp.conf
# XSS 공격 방어를 위한 CSP

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;

지역 기반 접근 제어

# security/geo-blocking.conf
# GeoIP2를 이용한 국가별 차단 (선택사항)

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
    $geoip2_country_code country iso_code;
}

map $geoip2_country_code $blocked_country {
    default 0;
    CN 1;
    RU 1;
}

8단계: 로드밸런싱 및 고가용성

트래픽 증가에 대비한 로드밸런싱을 구성합니다.

다중 백엔드 서버 설정

# upstream/backend-servers.conf 업데이트
upstream app_backend {
    least_conn;  # 연결 수 기반 로드밸런싱
    server 127.0.0.1:3000 weight=3;
    server 127.0.0.1:3001 weight=2;
    server 127.0.0.1:3002 weight=1 backup;
    
    keepalive 32;
}

헬스체크 설정

# 기본 헬스체크 (Nginx Plus 없이)
upstream app_backend {
    server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
}

9단계: 캐싱 전략 구현

성능 향상을 위한 다층 캐싱을 구현합니다.

프록시 캐시 설정

# performance/proxy-cache.conf
proxy_cache_path /var/cache/nginx/main
                 levels=1:2
                 keys_zone=main_cache:100m
                 inactive=60m
                 max_size=1g;

# 사이트 설정에 적용
location / {
    proxy_cache main_cache;
    proxy_cache_valid 200 302 5m;
    proxy_cache_valid 404 1m;
    proxy_cache_use_stale error timeout updating;
    
    add_header X-Cache-Status $upstream_cache_status;
    proxy_pass http://app_backend;
}

정적 파일 캐싱 최적화

# 정적 파일별 세분화된 캐싱
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header Vary "Accept-Encoding";
}

location ~* \.(css|js)$ {
    expires 1M;
    add_header Cache-Control "public";
    add_header Vary "Accept-Encoding";
}

10단계: 고급 기능 및 특수 요구사항

마지막으로 특수한 요구사항에 맞는 고급 기능을 구현합니다.

WebSocket 지원

# proxy/websocket.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

location /ws {
    proxy_pass http://app_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

API 게이트웨이 기능

# 마이크로서비스 라우팅
location /api/users/ {
    limit_req zone=api burst=50 nodelay;
    proxy_pass http://user_service;
}

location /api/orders/ {
    limit_req zone=api burst=30 nodelay;
    proxy_pass http://order_service;
}

이미지 최적화

# media/image-processing.conf
location ~ ^/images/resize/(\d+)x(\d+)/(.+)$ {
    image_filter resize $1 $2;
    image_filter_jpeg_quality 85;
    root /var/www/images;
    expires 1M;
}

설정 검증 및 배포 스크립트

자동화된 검증 스크립트

#!/bin/bash
# scripts/deploy-config.sh
# 설정 배포 전 검증

echo "1. 설정 문법 검사..."
nginx -t

if [ $? -ne 0 ]; then
    echo "설정 오류 발견. 배포 중단."
    exit 1
fi

echo "2. SSL 인증서 확인..."
for cert in /etc/nginx/certs/*/fullchain.pem; do
    if [ -f "$cert" ]; then
        openssl x509 -in "$cert" -noout -checkend 2592000
    fi
done

echo "3. 백업 생성..."
tar -czf "/backup/nginx-$(date +%Y%m%d-%H%M%S).tar.gz" /etc/nginx/

echo "4. 설정 리로드..."
nginx -s reload

echo "배포 완료!"

결론

Nginx 설정은 단계적으로 접근하는 것이 핵심입니다. 기본 구조와 필수 보안 설정부터 시작하여, 점진적으로 성능 최적화와 고급 기능을 추가해나가는 것이 안정적이고 관리하기 쉬운 인프라를 구축하는 방법입니다.

각 단계에서 충분한 테스트를 거치고, 다음 단계로 넘어가기 전에 현재 설정이 안정적으로 동작하는지 확인하는 것이 중요합니다. 또한 설정의 변경사항을 버전 관리 시스템을 통해 추적하고, 정기적인 백업을 통해 장애에 대비하는 것도 필수적입니다.




댓글 남기기