[Nginx] request method 마다 limit_req 설정하기

miinhho·2025년 6월 27일
post-thumbnail

Nginx 를 사용해서 과도한 요청을 제한시키며, 특정 api 에서 http request method 마다 다른 제한 값을 설정해야하는 상황이 있었다.

다만 $request_method 를 사용해서 if 문 에 limit_req 를 사용하면 오류가 난다.

location /api/ {
    if ($request_method = GET) {
        limit_req zone=api burst=20 nodelay;
    }
    # ...
}

위와 같은 코드는 작동하지 않는다.

우선 Github Copilot (Claude 4) 에게 물어봤지만, 비슷한 오류가 나거나 내가 바라는 동작과는 거리가 멀었다.



하지만... Stack Overflow 에서 빛과 같은 게시물을 볼 수 있었다.
Nginx Rate limit GET of POST requests only at a location

http {
  ... # your nginx.conf here
  
  # Maps ip address to $limit variable if request is of type POST
  map $request_method $limit {
    default         "";
    POST            $binary_remote_addr;
  }
  
  # Creates 10mb zone in memory for storing binary ips
  limit_req_zone $limit zone=my_zone:10m rate=1r/s;
}

**Rate limiting for the entire NGINX process:**
http {
    ... # your nginx.conf here
    limit_req zone=global_zone;
}

Nginx 의 map 을 통해 $request_method 마다 필터링을 해서 request method 마다 limit_req 를 설정하는 것을 구현한 답이였다.

나는 위 방법을 따라 아래와 같은 설정으로 사용하였다.

# nginx.conf
http {
    map $request_method $limit_post {
        default "";
        POST    $binary_remote_addr;
    }
    
    map $request_method $limit_get {
        default "";
        GET     $binary_remote_addr;
    }
    
    map $request_method $limit_put {
        default "";
        PUT     $binary_remote_addr;
        PATCH   $binary_remote_addr;
    }

    map $request_method $limit_delete {
        default "";
        DELETE  $binary_remote_addr;
    }

    limit_req_zone $limit_get zone=get_only:10m rate=60r/s;
    limit_req_zone $limit_post zone=post_only:10m rate=10r/s;
    limit_req_zone $limit_put zone=put_only:10m rate=5r/s;
    limit_req_zone $limit_delete zone=delete_only:10m rate=3r/s;
    
    # ...
 }
 
 # app.conf
 server {
    location ~ "/post/[^/]/(like|comments)$" {
        limit_req zone=get_only burst=20 nodelay;
        limit_req zone=post_only burst=5 nodelay;
        limit_req zone=put_only burst=2 nodelay;
        limit_req zone=delete_only burst=1 nodelay;
        # ...
    }
}

비록 Nginx 에서 iflimit_req 의 사용이 불가능하지만, 위와 같은 방법으로 GET, POST, PUT, PATCH, DELETE 마다 요청을 제한시킬 수 있었다.


profile
재미있는 걸 좋아합니다

0개의 댓글