Nginx Rate Limiting

Nginx limit_req_zone 기반 요청 속도 제한 설정 — 일반/관리 경로 zone 분리 전략

마지막 수정: 2026-05

Nginx Rate Limiting

단시간에 대량 요청을 보내는 DDoS, 브루트포스, 자동화 스캔을 제한한다.
limit_req_zone으로 zone을 정의하고, limit_req로 각 location에 적용한다.


핵심 개념

지시어설명
limit_req_zone제한 기준(키), 메모리 크기, 허용 속도(rate) 정의
limit_reqzone 적용 및 burst / nodelay 설정
burstrate 초과 시 대기열에 쌓을 수 있는 추가 요청 수
nodelayburst 범위 내 요청을 지연 없이 즉시 처리 (없으면 rate에 맞춰 지연 처리)

rate 계산 예시

  • rate=10r/s → 초당 10건, 즉 100ms마다 1건 허용
  • burst=20 nodelay → 순간 최대 30건(10 + 20)까지 허용, 초과분은 즉시 503

Zone 분리 전략

경로 특성에 따라 zone을 분리한다. 하나의 zone으로 전체를 제한하면 정상 트래픽도 영향받는다.

Zone 이름적용 경로허용 속도용도
general/ (전체)30r/s일반 페이지 요청
api/api/10r/sAPI 엔드포인트
admin/admin/, /actuator/5r/m관리 경로 — 사람이 직접 접근하므로 분당 기준

전체 설정 예시

# /etc/nginx/nginx.conf — http 블록 안에 선언

http {
    # Zone 정의
    # $binary_remote_addr: IP당 적용 (binary 형식이 메모리 절약)
    # 10m: 약 16만 IP 추적 가능한 메모리

    limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
    limit_req_zone $binary_remote_addr zone=api:10m     rate=10r/s;
    limit_req_zone $binary_remote_addr zone=admin:10m   rate=5r/m;

    # 제한 초과 시 응답 코드 (기본 503 → 429로 변경)
    limit_req_status 429;

    include /etc/nginx/conf.d/*.conf;
}
# /etc/nginx/conf.d/your-site.conf — server 블록

server {
    listen 443 ssl;
    server_name example.com;

    # 전체 경로 — 일반 rate 적용
    location / {
        limit_req zone=general burst=50 nodelay;
        proxy_pass http://127.0.0.1:8080;
    }

    # API 경로 — 더 엄격하게
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://127.0.0.1:8080;
    }

    # 관리/모니터링 경로 — 가장 엄격하게
    location ~* "^/(admin|actuator|management)/" {
        limit_req zone=admin burst=3 nodelay;
        proxy_pass http://127.0.0.1:8080;
    }
}

burst / nodelay 동작 비교

rate=10r/s, burst=5 로 설정 시 초당 20건 요청이 들어오는 경우:

[ nodelay 있음 ]
  → 15건 즉시 처리 (rate 10 + burst 5)
  → 나머지 5건 즉시 429 반환

[ nodelay 없음 ]
  → 10건 즉시 처리
  → 5건은 100ms 간격으로 지연 처리 (대기열)
  → 나머지 5건 429 반환

API처럼 응답 지연이 민감한 경로는 nodelay 사용을 권장한다.



r/m vs r/s 단위 주의

rate=5r/m처럼 분당(r/m) 단위를 사용하면 브라우저 한 번의 페이지 로드에서도 CSS, JS, 이미지 등 자산 요청이 동시에 여러 건 발생하여 503이 빈번하게 나타날 수 있다.

# ❌ r/m 단위 — 페이지 로드 시 503 발생 가능
limit_req_zone $binary_remote_addr zone=admin:10m rate=5r/m;

# ✅ r/s 단위 권장
limit_req_zone $binary_remote_addr zone=general:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=admin:10m   rate=2r/s;

burst 없이 rate만 설정하면 동시 요청이 즉시 차단되므로 burst 설정 필수:

limit_req zone=general burst=20 nodelay;
limit_req zone=admin   burst=5  nodelay;

429 응답 커스텀

server {
    # 429 발생 시 커스텀 응답
    error_page 429 /rate-limit.html;

    location = /rate-limit.html {
        root /usr/share/nginx/html;
        internal;
    }
}

적용 방법

# 설정 검사
sudo nginx -t

# 재시작 없이 반영
sudo nginx -s reload

제한 초과 로그 확인

# 429 발생 확인
sudo grep ' 429 ' /var/log/nginx/access.log | tail -20

# IP별 429 빈도
sudo grep ' 429 ' /var/log/nginx/access.log \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -10