Установите limit_req для определенного местоположения в Nginx Ingress - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь настроить параметр ограничения скорости limit_req для определенного пути в Kubernetes ingress-nginx, чтобы предотвратить грубую аутентификацию.

Я определил limit_req_zone, используя ConfigMap:

http-snippet: |
      limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;

Далее я использую аннотацию для добавления пользовательского блока местоположения:

nginx.ingress.kubernetes.io/configuration-snippet: |
  location ~* "^/authenticate$" {
    limit_req zone=authentication_ratelimit nodelay;
    more_set_headers "x-test: matched";
  }

В результате получается nginx.conf:

server {
# - - 8< - -

  location / {
    # - - 8< - -

    location ~* "^/authenticate$" {
      limit_req zone=authentication_ratelimit nodelay;
      more_set_headers "x-test: matched";
    }

    proxy_pass http://upstream_balancer;

    proxy_redirect                          off;
}

В результате /authenticate всегда возвращает HTTP 503 (с заголовком x-test). Сообщение из журналов входного доступа:

<ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d

Я подозреваю, что это может быть связано с конфликтом между вложенным блоком местоположения и proxy_pass (но это только дикое предположение).

Какие еще варианты я пробовал?

  • использовать server-snippet аннотацию вместо configuration-snippet - /authenticate возвращает 404, поскольку proxy_pass не настроено
  • use nginx.ingress.kubernetes.io/limit-rpm annotation - вызывает ограничение скорости для всего приложения, что не то, что я хочу.

Вопрос: почему пользовательский блок местоположения отвечает 503? Как я могу отладить это? Будет ли повышение уровня ведения журнала nginx давать более подробную информацию о 503? Или более общий вопрос: могу ли я добавить пользовательские блоки местоположения в ingress-nginx?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Это можно сделать с помощью карты и того факта, что Запросы с пустым значением ключа не учитываются.

http-snippets: |
  map $uri $with_limit_req {
    default 0;
    "~*^/authenticate$" 1;
  }
  map $with_limit_req $auth_limit_req_key {
    default '';
    '1'     $binary_remote_addr; # the limit key
  }
  limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;

И используйте аннотацию для добавления пользовательского блока местоположения:

nginx.ingress.kubernetes.io/configuration-snippet: |
  limit_req zone=authentication_ratelimit nodelay;

Или, если вы используете вход из nginxinc

nginx.org/location-snippets:
  limit_req zone=authentication_ratelimit nodelay;

в этом случае проверьте, нужно ли обрабатывать запросы с ограниченной скоростью на уровне карты.

И мое мнение: лучше ограничивать запросы на уровне приложения, как если бы вы установили ограничение скорости на уровне входа, это зависит от количества входящих блоков.

0 голосов
/ 07 января 2019

Это может звучать смешно, но не могли бы вы просто создать аннотацию так:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-with-annotations
  annotations:
    nginx.org/server-snippets: |
      limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
      location ~* "^/authenticate$" {
         limit_req zone=mylimit burst=10 nodelay;
         more_set_headers "x-test: matched";
      }

Потому что, похоже, вы забыли определить limit_req_zone до того, как начали использовать его в директиве location. Я использовал официальную документацию о limit_req

...