Nginx Limit_conn 상속

Nginx Limit_conn 상속

나는 Nginx에서 실행되는 Drupal을 Limit_conn 및 Limit_req를 사용하여 간단한 DDoS로부터 보호하려고 합니다. 그러나 limit_conn지시문 상속으로 인해 설명할 수 없는 이상한 동작이 발생했습니다 .

내 nginx(1.8.0) 구성을 최소한으로 줄였는데, 이는 문제를 보여줍니다.

limit_conn_zone $binary_remote_addr zone=perip:10m;

server {
    server_name test.dev;
    root /var/nginx/drupal; ## <-- Your only path reference.

    #Allow not more than 10 simultaneous connections from one address.
    limit_conn perip  10;

    location / {
        #limit_conn perip 1;
        # This is cool because no php is touched for static content
        try_files $uri @rewrite;
    }

    location @rewrite {
        # Clean URLs are handled in drupal_environment_initialize().
        rewrite ^ /index.php;
    }

    location ~ \.php$ {
        #Allow not more than 1 simultaneous *connection_to_PHP* from one address.
        limit_conn perip 1; 

        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi.conf;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
}

보시다시피 동시 연결 수를 모든 요청에 ​​대해 10으로 제한하고 PHP 백엔드에 대해 4로 제한하고 싶습니다.(이 예에서는 4 연결을 1로 수정했으므로 트리거하기가 더 쉬울 것입니다)

Nginx 문서는 다음 위치에 있습니다.http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn다음과 같이 말합니다.

limit_conn이러한 지시어는 현재 수준에 지시어가 없는 경우에만 이전 수준에서 상속됩니다 .

limit_conn하지만 내 테스트에서 이상한 일이 발생했습니다. nginx가 블록 내부의 지시문을 무시하는 것 같습니다 location ~ \.php$.

  1. 5개의 동시 연결로 이 구성을 테스트하면 ab -n 100 -c 5 http://test.dev/차단이 발생하지 않습니다.
    제한을 11개의 nginx로 올리 -c 11자마자 요청을 차단하기 시작합니다.
  2. 전역 연결 제한을 10에서 5로 수정하면 nginx는 6개 이상의 연결을 제한합니다( ). 블록 -c 6의 지시문이 무시되는 것처럼 보입니다 .location ~ \.php$
  3. 서버 수준에서 지시문 을 삭제하면 블록 conn_limit의 지시문이 location ~ \.php$갑자기 작동하기 시작합니다!
  4. 더 혼란스러운 점은 블록 conn_limit에 지시문 을 추가하면 location /전역 지시문을 올바르게 덮어쓰게 된다는 것입니다!

어쩌면 문제가 try_files지시문이나 다중 리디렉션에 있는 것일까요? 누군가가 conn_limit예상한 대로 지시문을 덮어쓰지 않는 이유를 설명할 수 있다면 매우 감사하겠습니다 .

답변1

@AlexeyTen 덕분에 질문에 답할 수 있었으면 좋겠습니다.

중요한 점은 다음 두 가지입니다.

  • 지시문은 limit_conn요청당 한 번만 처리됩니다!
  • limit_conn이러한 지시어는 현재 수준에 지시어가 없는 경우에만 이전 수준에서 상속됩니다 .

요약: 지시문이 있으면 limit_connnginx는 실행 체인의 하위 블록을 살펴보고, 없으면 limit_conn상위 블록을 처리합니다. 그 후에는 다른 모든 limit_conn지시문이 무시됩니다.

나는 내 예를 들어 설명하려고 노력합니다.

제가 게시한 예에서 "http://test.dev/" 요청이 도착하면 처음에는 nginx가 수준 limit_conn에서 처리하지 server않고 일치하는 위치를 찾기 위해 기다립니다 location /. 하지만 이 수준에는 지시문이 없으므로 limit_connnginx는 해당 server수준의 지시문을 처리합니다. 그 이후에는 모든 limit_conn지시문이 무시됩니다. 이미 처리되었습니다. 이는 내 테스트 1-3을 설명합니다.

테스트 4에서는 nginx가 limit_connlocation에서 지시문을 찾아서 location /처리하지만, 다시 location location @rewriteno 에서 지시문 limit_conn을 발견하여 at 지시문을 location /처리합니다. 다시 말하지만, 우리는 location ~ \.php$블록을 무시하고 있습니다.

관련 정보