NGINX에서 속도 제한을 적용하는 방법

NGINX의 속도 제한은 서버가 처리하는 트래픽 양을 제어하는 ​​데 중요한 기능입니다. 이는 DDoS 또는 높은 트래픽 급증과 같은 악의적인 공격으로 인해 발생할 수 있는 단기간에 너무 많은 요청으로 인해 서버가 압도되는 것을 방지하는 데 도움이 됩니다. 속도 제한을 구현하면 리소스가 효율적으로 사용되고 합법적인 사용자가 중단 없이 서비스에 액세스할 수 있습니다.

이 가이드에서는 NGINX에서 속도 제한을 구성하는 방법을 보여주고 들어오는 트래픽을 효과적으로 관리하고 제어하는 ​​데 도움이 되는 명확한 지침을 제공합니다.

NGINX의 속도 제한 지시문 이해

주요 NGINX 속도 제한 지시어

NGINX는 각각 고유한 기능을 제공하는 특정 지시문을 사용하여 속도 제한을 구성합니다.

  • 한도_요구_구역: NGINX의limit_req_zone 지시어는 속도 제한 정보를 저장하기 위한 공유 메모리 영역을 설정합니다. http 컨텍스트에 위치하며 허용 가능한 요청 속도를 결정하고 속도 제한에 대한 기준을 효과적으로 설정합니다.
  • 한도_요구: 위치 컨텍스트에서 활용되는limit_req 지시어는limit_req_zone에 의해 설정된 속도 제한을 적용합니다. 특정 위치나 URL에 이러한 제한을 적용하여 이러한 엔드포인트에 대한 액세스 빈도를 제어합니다.
  • 한도_요구_상태: 위치 컨텍스트에 있는limit_req_status 지시문은 요청 속도가 제한을 초과할 때 반환되는 HTTP 상태 코드를 지정합니다. 이 피드백 메커니즘은 허용된 요청 빈도를 초과할 때 사용자나 자동화 시스템에 알리는 데 중요합니다.

속도 제한 구성 생성

NGINX에서 속도 제한을 구현하려면 NGINX 구성 파일에 적절한 지시어를 삽입하세요. 다음 기본 예를 고려하십시오.

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    server {
        ...
        location / {
            limit_req zone=mylimit burst=10;
            ...
        }
    }
}

이 구성에서limit_req_zone 지시어는 'mylimit'라는 메모리 영역을 설정하여 각 클라이언트 IP 주소($binary_remote_addr)에서 초당 5개의 요청(5r/s)을 허용합니다. 그런 다음limit_req 지시어는 이 속도 제한을 루트 위치(/)에 적용하고 버스트 용량은 10개 요청으로 적용하여 엄격한 속도 제한과 합법적인 트래픽 급증에 대한 유연성 사이의 균형을 제공합니다.

NGINX의 속도 제한: 실제 예

기본 속도 제한 구성

이 섹션에서는 NGINX에서 서버 전체에 적용되는 기본 속도 제한 구성을 살펴봅니다. 목표는 사용자 요청을 서버로 제한하여 안정적인 성능을 보장하고 과부하 위험을 완화하는 것입니다.

예: 서버 전체 속도 제한

다음 NGINX 구성을 고려하십시오.

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req zone=mylimit burst=5;
            proxy_pass http://backend;
        }
    }
}

이 구성은 IP 주소에 정의된 대로 각 클라이언트에 대해 초당 2개의 요청 제한을 설정합니다($binary_remote_addr). 주요 구성 요소를 분석해 보겠습니다.

  • 한도_요구_구역: 속도 제한 상태를 10MB 크기로 저장하기 위한 메모리 영역(mylimit)을 정의합니다. 속도 제한을 초당 요청 2개(2r/s)로 설정합니다.
  • 서버 블록: example.com으로 들어오는 트래픽을 포트 80에서 수신합니다.
  • 위치 블록: 루트 URL(/)에 속도 제한을 적용합니다. 버스트 매개변수는 최대 5개의 요청 버스트를 허용하여 짧은 트래픽 급증에 대한 유연성을 제공합니다. Proxy_pass 지시문은 요청을 지정된 백엔드 서버로 전달합니다.
  • 버스트 매개변수:limit_req 지시문의burst=5 설정은 요청의 단기 증가를 허용하며 설정된 속도보다 최대 5개의 추가 요청을 허용합니다. 이 기능은 사용자 경험에 영향을 주지 않고 갑작스럽고 합법적인 트래픽 증가를 처리하는 데 중요합니다.
  • 프록시 패스: Proxy_pass http://backend; 지시문은 트래픽을 백엔드 서버로 전달합니다. 이는 부하 분산 시나리오나 NGINX가 역방향 프록시로 작동할 때 일반적으로 사용됩니다.

고급 속도 제한 예

위치에 따라 다른 속도 제한

더 복잡한 시나리오에서는 다양한 애플리케이션 부분에 다양한 속도 제한을 적용해야 할 수도 있습니다. 이는 특정 엔드포인트가 리소스 집약적이거나 남용되기 쉬운 경우에 특히 유용합니다.

다음 구성을 고려하십시오.

http {
    limit_req_zone $binary_remote_addr zone=low:10m rate=1r/s;
    limit_req_zone $binary_remote_addr zone=high:10m rate=10r/s;

    server {
        listen 80;
        server_name example.com;

        location /api/low {
            limit_req zone=low burst=3;
            proxy_pass http://backend;
        }

        location /api/high {
            limit_req zone=high burst=20;
            proxy_pass http://backend;
        }
    }
}

이 구성은 /api/low 위치에 더 낮은 속도 제한(초당 1개 요청)을 적용하고 /api/high 위치에 더 높은 속도 제한(초당 10개 요청)을 적용합니다.

추가 Nginx 속도 제한 예

요청 유형에 따른 속도 제한

GET, POST 또는 PUT 요청과 같은 특정 요청을 기반으로 속도 제한을 구성할 수 있습니다. 이는 남용에 더 취약하거나 서버 리소스에 더 큰 영향을 미치는 특정 엔드포인트를 보호하려는 경우 특히 유용합니다.

if 지시어와 $request_method 변수를 사용하여 특정 요청 유형에 속도 제한을 적용할 수 있습니다. 예는 다음과 같습니다.

http {
    limit_req_zone $binary_remote_addr zone=get_limit:10m rate=5r/s;
    limit_req_zone $binary_remote_addr zone=post_limit:10m rate=2r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($request_method = GET) {
                limit_req zone=get_limit burst=10;
            }

            if ($request_method = POST) {
                limit_req zone=post_limit burst=5;
            }

            proxy_pass http://backend;
        }
    }
}

이 구성에서는 두 가지 별도의 속도 제한을 설정했습니다. 하나는 GET 요청(초당 5개 요청)이고 다른 하나는 POST 요청(초당 2개 요청)입니다.

사용자 에이전트 기반 속도 제한

또 다른 유용한 기술은 클라이언트가 보낸 User-Agent 헤더를 기반으로 속도 제한을 적용하는 것입니다. 이를 통해 문제를 일으키는 특정 봇이나 크롤러로부터 서비스를 보호할 수 있습니다.

User-Agent를 기반으로 속도 제한을 구현하려면 map 지시문과 $http_user_agent 변수를 사용할 수 있습니다.

예는 다음과 같습니다.

http {
    map $http_user_agent $limit_bots {
        default 0;
        ~*(Googlebot|Bingbot) 1;
    }

    limit_req_zone $binary_remote_addr zone=bot_limit:10m rate=1r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($limit_bots) {
                limit_req zone=bot_limit burst=2;
            }

            proxy_pass http://backend;
        }
    }
}

이 예에서는 User-Agent 헤더가 'Googlebot' 또는 'Bingbot'과 일치하는 경우 $limit_bots 변수를 1로 설정하는 map 지시어를 정의했습니다. 그런 다음 이러한 봇의 요청에 초당 1개의 요청 비율 제한을 적용합니다.

속도 제한에서 IP를 화이트리스트에 추가

때로는 신뢰할 수 있는 파트너나 내부 서비스와 같은 특정 IP 주소를 속도 제한에서 제외하려고 할 수도 있습니다. 이를 달성하려면 geo 지시어를 다음과 함께 사용할 수 있습니다. if 지령.

예는 다음과 같습니다.

http {
    geo $rate_limit {
        default 1;
        192.168.0.0/24 0;
        10.0.0.0/8 0;
    }

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

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($rate_limit) {
                limit_req zone=mylimit burst=10;
            }

            proxy_pass http://backend;
        }
    }
}

분산 환경에서 속도 제한 조정

여러 Nginx 인스턴스가 분산 환경에서 실행 중인 경우 모든 인스턴스에서 속도 제한이 일관되게 유지되도록 할 수 있습니다. 이를 달성하기 위해 Redis와 같은 중앙 집중식 데이터 저장소를 사용하여 속도 제한을 관리할 수 있습니다. 이렇게 하면 모든 Nginx 인스턴스 간에 공유되는 전역 속도 제한을 유지할 수 있습니다.

Redis로 속도 제한을 설정하려면 nginx-module-redis 모듈을 설치하고 구성해야 합니다. 모듈을 설치한 후에는 속도 제한에 Redis를 사용하도록 Nginx 구성을 업데이트할 수 있습니다.

예는 다음과 같습니다.

load_module modules/ngx_http_redis_module.so;

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    upstream redis_server {
        server 127.0.0.1:6379;
        keepalive 32;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req_redis zone=mylimit burst=10 redis_server=redis_server;
            proxy_pass http://backend;
        }
    }
}

이 예에서는 Redis 서버에 대한 업스트림 블록을 정의하고 표준 Limit_req 지시문 대신 Limit_req_redis 지시문을 사용하도록 위치 블록을 업데이트했습니다. 이 구성을 사용하면 공유 Redis 데이터 저장소를 사용하여 속도 제한이 적용되어 여러 Nginx 인스턴스에 걸쳐 일관된 속도 제한을 제공할 수 있습니다.

동적 속도 제한

어떤 상황에서는 특정 조건이나 서버의 현재 로드에 따라 속도 제한을 동적으로 조정해야 할 수도 있습니다. 예를 들어, 서버 리소스를 더 잘 관리하기 위해 트래픽이 가장 많은 시간대에 더 엄격한 비율 제한을 적용할 수 있습니다.

동적 속도 제한을 구현하려면 다음을 사용할 수 있습니다. map 특정 조건에 따라 비율 제한을 정의하는 지침입니다.

예는 다음과 같습니다.

http {
    map $http_x_traffic $dynamic_rate {
        default "5r/s";
        high "2r/s";
    }

    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=$dynamic_rate;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req zone=mylimit burst=10;
            proxy_pass http://backend;
        }
    }
}

이 구성에서는 사용자 정의 헤더 X-Traffic에서 파생된 $http_x_traffic 변수를 사용합니다. 이 헤더의 값을 기반으로 속도 제한을 동적으로 설정합니다. 헤더 값이 "높음"이면 초당 요청 2개라는 더 엄격한 속도 제한을 적용합니다. 그렇지 않으면 초당 5개의 요청이라는 기본 속도를 사용합니다.

이 예에서는 백엔드 서버 또는 인프라의 다른 구성 요소가 원하는 조건에 따라 X-Traffic 헤더를 설정한다고 가정합니다.

NGINX 구성에서 속도 제한 테스트

컬을 사용하여 속도 제한 확인

단순 요청 테스트에 컬 사용하기

NGINX에서 속도 제한 설정의 효율성을 검증하려면 HTTP 요청 전송을 위한 명령줄 도구인 컬이 매우 유용한 것으로 입증되었습니다. 여러 요청을 서버에 빠르게 보낼 수 있어 속도 제한이 활성화되어 있는지 평가하는 데 도움이 됩니다.

for i in {1..10}; do curl -I http://example.com; done
  • 이 명령은 http://example.com을 대상으로 서버에 10개의 HEAD 요청을 보냅니다.
  • 이러한 요청의 HTTP 응답 헤더를 분석하여 속도 제한 기능을 확인하세요.
  • 요청 비율이 지정된 제한을 초과하면 NGINX는 429 요청이 너무 많음 상태 코드를 반환해야 합니다.

Apache Bench로 테스트(ab)

Apache Bench를 사용하여 서버 응답 벤치마킹

Apache Bench(ab)는 트래픽이 많은 조건을 시뮬레이션하여 속도 제한을 테스트하는 데 이상적인 효과적인 벤치마킹 도구입니다. 요청이 급증할 때 NGINX 서버가 어떻게 작동하는지 이해하는 데 도움이 됩니다.

ab -n 100 -c 10 http://example.com/
  • 이 명령은 ab에게 동시성 수준 10으로 http://example.com에 100개의 요청을 보내도록 지시합니다.
  • ab의 출력은 속도 제한 효과에 대한 통찰력을 제공합니다.
  • 출력에서 실패한 요청 수에 집중하세요. 이는 NGINX 속도 제한 구성의 설정과 일치해야 합니다.

NGINX 구성을 테스트하는 가장 좋은 방법을 사용하면 속도 제한 규칙이 의도한 대로 작동하는지 확인할 수 있습니다.

결론

NGINX에서 속도 제한을 구성하면 과도한 트래픽과 잠재적인 남용으로부터 서버를 보호할 수 있습니다. 이는 서비스의 성능과 가용성을 유지하는 데 도움이 되며 합법적인 사용자에게 더 나은 경험을 보장합니다. 보안과 접근성의 균형을 맞추기 위해 속도 제한 설정을 정기적으로 모니터링하고 조정하세요. 이러한 제어를 구현하는 것은 서버 리소스를 효율적으로 관리하는 데 매우 중요합니다.

Joshua James

코멘트를 남겨주세요