API Рейт-ліміти: обмеження кількості запитів за одиницю часу

🌐 Цей документ доступний українською та англійською мовами. Використовуйте перемикач у правому верхньому куті, щоб змінити версію.

1. Загальний опис

Рейт-лімітування (англ. — Rate limiting) — це стратегія для обмеження мережевого трафіку.

API рейт-ліміти (англ. — API rate limits) — обмеження кількості HTTP-запитів до сервісу чи маршруту за заданий період секунд, хвилин, годин, днів, місяців або років.

Механізм рейт-лімітів реалізований на базі Rate-Limiting-плагіну для Kong API Gateway. Якщо сервіс/маршрут не має рівня аутентифікації, ліміт буде встановлено для IP-адреси клієнта. В іншому випадку для лімітів можна використовувати значення власного заголовка запита, що містить інформацію про користувача: наприклад, ідентифікатор користувача, його роль чи ідентифікатор організації, яку він представляє. Такий заголовок можна додати засобами Kong OIDC-плагіну.

Важливо, щоб плагін rate-limiting виконувався після OIDC-плагіну!

Тобто пріоритет OIDC-плагіну має бути вищим за значення пріоритету для плагіну rate-limiting, який за замовчуванням становить 910. Цей механізм більш детально описаний нижче.

Всі рейт-ліміти обчислюються виключно в межах одного екземпляру Kong API Gateway. Якщо кількість екземплярів Kong більше одного, то загальна кількість запитів від користувача може бути більшою в n разів за значення, встановлене в налаштуваннях для лімітів, де n — це кількість розгорнутих екземплярів Kong API Gateway.

Kong API Gateway розгортається на рівні сервісів реєстру.

Приклад 1. Верхньорівнева діаграма функціонування рейт-лімітів у Kong

Kong Rate Limits.drawio

2. Принцип роботи рейт-лімітів для неавтентифікованих користувачів

Для неавтентифікованих користувачів можливо встановити ліміт лише за IP-адресою (config.limit_by: ip).

Приклад 2. Схема роботи рейт-лімітів для неавтентифікованих користувачів
Diagram
  1. Користувач надсилає запит до платформи, який надходить до Kong API Gateway.

  2. Запит обробляється Kong Rate-Limiting плагіном, який, базуючись на правилах для конкретного сервісу/маршруту, визначає, чи досягнуто ліміт запитів для IP-адреси користувача.

  3. Якщо ліміт запитів від користувача не досягнуто, запит перенаправляється на відповідний сервіс платформи для подальшого опрацювання.

  4. Користувач отримує відповідь від сервісу.

  5. Якщо ліміт запитів досягнуто, плагін Rate-Limiting повертає відповідь з помилкою HTTP 429.

3. Принцип роботи рейт-лімітів для автентифікованих користувачів

Якщо сервіс/маршрут має рівень автентифікації, то ліміт можна встановити не лише для IP-адреси клієнта, а й для конкретного автентифікованого користувача чи їх групи.

В такому разі для обчислення ліміту можна використовувати значення власного заголовка "token-claim" запита, що містить інформацію про користувача: наприклад, ідентифікатор користувача, роль, або ідентифікатор організації, яку він представляє. Такий заголовок можна додати засобами Kong OIDC-плагіну.

Приклад 3. Принцип роботи рейт-лімітів для автентифікованих користувачів
Diagram
  1. Користувач надсилає запит до платформи, який надходить до Kong API Gateway.

  2. Першим запит обробляє Kong OIDC-плагін, який перевіряє сесію користувача.
    Якщо користувач успішно пройшов автентифікацію (існує активна сесія), то OIDC-плагін додає до запита заголовки із JWT-токенами користувача та заголовок "token-claim", що містить значення атрибута (claim) з токена доступу автентифікованого користувача. Надалі значення цього заголовка використовується плагіном rate-limiting для обчислення лімітів для автентифікованого користувача чи групи таких користувачів.

  3. Обробка запита передається до наступного плагіну — Rate-Limiting.

  4. Плагін Rate-Limiting, базуючись на правилах для конкретного сервісу/маршруту, визначає, чи досягнуто ліміт запитів для користувача.
    Ліміт може бути встановлений як за IP-адресою, так і на основі значення заголовка "token-claim".

  5. Якщо ліміт запитів від користувача не досягнуто, запит перенаправляється на відповідний сервіс платформи для подальшого опрацювання.

  6. Користувач отримує відповідь від сервісу.

  7. Якщо ліміт запитів досягнуто, плагін Rate-Limiting повертає відповідь з помилкою HTTP 429.

Налаштування власного заголовка для автентифікованого користувача

Для обчислення лімітів для автентифікованих користувачів можна використовувати значення заголовка "token-claim" запита, що містить інформацію про користувача. Встановити значення для цього заголовка можна в налаштуваннях OIDC-плагіну для Kong. Цей заголовок може містити значення кореневого атрибута (claim) з JWT-токена доступу користувача.

Приклад 4. Приклад налаштування OIDC-плагіну KONG для додавання заголовка "token-claim"
OIDC Config
config:
  token_claim_header_value: "sub"

В такому випадку, після обробки запита OIDC-плагіном, до запита буде додано заголовок "token-claim", значення для якого буде взято з атрибута "sub" (claim) токена доступу користувача.

Тобто ми отримаємо заголовок "token-claim", що містить ідентифікатор користувача. Надалі цей заголовок можна використати в плагіні rate-limiting для обчислення ліміту за ідентифікатором користувача.

Rate-Limiting Config
config:
  limit_by: header
  header_name: "token-claim"

Для складніших варіантів обчислення ліміту можна додати власний атрибут до JWT-токена, що містить значення яке обчислюється. Зробити це можливо засобами Keycloak protocol mappers.

4. Налаштування рейт-лімітів адміністратором

4.1. Механізм налаштування рейт-лімітів

Механізм рейт-лімітів реалізований на базі Rate-Limiting-плагіну для Kong API Gateway.

Плагін Kong Rate-limiting є частиною Kong API Gateway та розгортається автоматично, разом з ним.

Механізм налаштування рейт-лімітів адміністратором є наступним:
  1. Адміністратор створює або редагує конфігураційний файл у форматі .yaml (.yml) з налаштуваннями для розширень Kong API Gateway — OIDC та Rate-Limiting.

  2. Адміністратор зберігає зміни в Gerrit-репозиторії у відповідному каталозі.

  3. Запускається процес Jenkins, який перевіряє наявність змін в репозиторії, та застосовує змінену конфігурацію для всіх запущених екземплярів Kong API Gateway в межах реєстру.

    Приклад 5. Схема налаштування рейт-лімітів адміністратором

    Rate limit configuration.drawio

Щоб налаштувати ліміти для автентифікованих користувачів чи їх груп, що об`єднані за певним атрибутом, необхідно спершу додати до запита заголовки з потрібними атрибутами. Базуючись на значеннях цих атрибутів, Rate-Limiting плагін зможе рахувати ліміти для кожного автентифікованого користувача чи групи індивідуально. Додати до запита заголовки з атрибутами користувача можна за допомогою OIDC-плагіну, який дозволяє додати власний заголовок "token-claim" зі значенням з JWT-токена (детальніше — у розділі Налаштування власного заголовка для автентифікованого користувача).

4.2. Процес налаштування лімітів за допомогою values.yaml

Налаштування рейт-лімітів відбувається у конфігураційному файлі values.yaml, у шаблоні розгортання відповідного реєстру. Метадані розгортання реєстрів із шаблону зберігаються у компоненті control-plane-gerrit — центральному репозиторії Gerrit.

Для прикладу розглянемо шаблон реєстру registry-tenant-template-registry-dev-minimal, що містить відповідну мінімальну конфігурацію ресурсів для реєстру, що розгортатиметься (див. сторінку Розгортання екземпляра реєстру).

  • За замовчуванням рейт-ліміти вимкнені.

  • Увімкнути їх може адміністратор безпеки з належними правами доступу.

  1. У локальному середовищі адміністратора відкрийте репозиторій центрального Gerrit — control-plane-gerrit.

  2. Відкрийте конфігураційний файл відповідного шаблону розгортання реєстру.

    Шлях до файлу може бути, наприклад, такий:

    resources/repositories/templates/registry-tenant-template-<registry-template-name>.git/deploy-templates/values.yaml

    Для прикладу ми використовуємо шаблон registry-tenant-template-registry-dev-minimal.git — шаблон розгортання реєстру із відповідним набором ресурсів (тут — мінімальна (minimal) конфігурація).

    api rate limits 1

  3. Всередині файлу values.yml знайдіть секцію параметрів, яка відповідає за налаштування плагінів Kong — kongPluginsConfig.

  4. Увімкніть плагін встановлення рейт-лімітів. Для цього встановіть значення параметра rateLimitingPluginEnable: true.

    Функціональність рейт-лімітів здатна обмежити кількість запитів за одиницю часу від вебпорталів (Кабінети посадової особи, отримувача послуг та адміністрування регламентів) до API внутрішніх сервісів реєстру.
  5. За замовчуванням налаштування Kong Rate Limiting плагіну виглядають наступним чином:

    Приклад 6. Налаштування values.yml для плагіну Kong Rate Limiting
    kongPluginsConfig:
      rateLimitingPluginEnable: false
      pluginsRateLimitByHeaderRequestsPerSecond: 10
      pluginsRateLimitByHeaderRequestsPerHour: 10000
      pluginsRateLimitByHeaderPolicy: "local"
      pluginsRateLimitByHeaderFaultTolerant: "true"
      pluginsRateLimitByHeaderHideClientHeaders: "false"
      pluginsRateLimitByHeaderHeaderName: "token-claim"
      pluginsRateLimitByIpRequestsPerSecond: 10
      pluginsRateLimitByIpRequestsPerHour: 10000
      pluginsRateLimitByIpPolicy: "local"
      pluginsRateLimitByIpFaultTolerant: "true"
      pluginsRateLimitByIpHideClientHeaders: "false"

    Поточна конфігурація показує налаштування рейт-лімітів за секунду та годину за:

    • заголовком (ByHeader) — лише для авторизованих користувачів — параметри pluginsRateLimitByHeaderRequestsPerSecond та pluginsRateLimitByHeaderRequestsPerHour відповідно;

    • IP-адресою (ByIp) — для будь-яких користувачів — параметри pluginsRateLimitByIpRequestsPerSecond та pluginsRateLimitByIpRequestsPerHour відповідно.

    Для коректної роботи плагіну, значення лімітів для параметрів LimitByHeader та LimitByIP мають бути однаковими.
    Повний список налаштувань та можливостей Kong Rate Limiting плагіну з описом параметрів доступний за посиланням.
  6. Після усіх налаштувань, виконайте commit до відповідного репозиторію. Після проходження збірки, нові ліміти набудуть чинності.

5. Відображення помилок на формах Кабінетів при перевищенні кількості запитів до сервісів

Перевищення кількості дозволених запитів від кабінетів адміністратора регламенту реєстру (admin-portal), посадової особи (officer-portal) та отримувача послуг (citizen-portal) до сервісів (бекенд-API) призводить до виникнення помилок, які відображаються на інтерфейсах користувачів.

Якщо при спробі доступу до сторінок кабінетів перевищено ліміт дозволеної кількості запитів до сервісів, то робота зі сторінкою блокується і відбувається перехід на сторінку з описом помилки HTTP 429.

Обмеження кількості запитів та час відновлення роботи зі сторінкою порталу встановлює адміністратор безпеки у налаштуваннях плагіну Rate Limiting.

Приклад 7. Приклади відображення помилок у кабінетах користувачів при перевищенні встановлених лімітів
Помилка при перевищенні лімітів запитів до сервера за встановлену одиницю часу у кабінеті адміністратора регламентів:

api rate limits 2

Перевищення лімітів запитів до сервера за встановлену одиницю часу у кабінеті посадової особи:

api rate limits 4

Перевищення лімітів запитів до сервера за встановлену одиницю часу у кабінеті отримувача послуг:

api rate limits 3