Перейти к основному содержимому

Правила фильтра: пути и методы

Правило — это связка «вот пути, вот разрешённые для них методы». Пути в правиле первичны: сначала выбираются правила, чьи шаблоны совпали с путём запроса, затем среди них проверяется метод.

http_filter:
mode: AllowList
rules:
- paths: # пути правила: точные значения или шаблоны по сегментам
- /api/orders
- /api/orders/*
methods: # методы, разрешённые для этих путей
- GET
- POST

Запрос разрешён, если хотя бы одно правило совпало и по пути, и по методу. Если ни одно правило не совпало по пути — запрос блокируется как неизвестный путь (403). Если путь совпал хотя бы с одним правилом, но ни одно из совпавших не разрешает метод — запрос блокируется как неразрешённый метод (405). Подробнее о кодах ответа — в статье Заблокированные запросы.

Как сопоставляется путь

Перед сопоставлением из пути запроса отбрасывается query-строка (всё после ?) и фрагмент (всё после #): политика описывает ресурсы, а не параметры запроса. Остаток сравнивается с шаблонами правил.

Запись в pathsТипЧто означает
/healthТочный путьСовпадает только с точно таким же путём. Записи без * сравниваются как строки целиком.
/api/users/*Шаблон по сегментам*ровно один непустой сегмент на этом месте.
/api/reports/**Шаблон по сегментам**любой хвост из нуля и более сегментов.
/api/**/reportШаблон по сегментам** допустим и в середине: любое количество сегментов между /api и /report.
/**Шаблон по сегментамЛюбой путь. Ограничение остаётся только по методам.

Сопоставление путей чувствительно к регистру: /API/Orders и /api/orders — разные пути.

Примеры для наглядности:

ШаблонПуть запросаРезультат
/health/healthсовпал
/health/healthz, /health/liveне совпал
/health/health?verbose=1совпал (query отброшена)
/api/users/*/api/users/42совпал
/api/users/*/api/users, /api/users/, /api/users/42/ordersне совпал
/api/**/api, /api/, /api/users, /api/users/42/ordersсовпал
/api/**/api-internalне совпал (** работает по сегментам, а не по символам)
/api/**/report/api/report, /api/v1/report, /api/v1/users/reportсовпал
/api/**/report/api/v1/usersне совпал
/**любой путьсовпал

Произвольные регулярные выражения и glob-подстановки внутри сегмента не поддерживаются осознанно: политика должна читаться однозначно любым, кто её проверяет. Записи вида /api*, /api/us*rs, /*.json, /api/**suffix отклоняются при старте (см. проверку конфигурации).

Как сопоставляется метод

  • Методы сравниваются без учёта регистра: get, GET и GeT эквивалентны.
  • Запись "*" разрешает любой метод для путей этого правила. Она должна быть единственной записью списка: смесь [GET, "*"] отклоняется при старте как вероятная ошибка оператора.
  • Никаких подразумеваемых методов нет: GET не включает HEAD, а POST не включает OPTIONS. Если клиенты используют HEAD или CORS-preflight OPTIONS, эти методы нужно перечислить явно.
  • В YAML запись "*" берётся в кавычки обязательно: без них символ * трактуется как ссылка на якорь (alias) и документ не разбирается.
- paths:
- /api/users/*
methods:
- "*" # любой метод для карточки пользователя

Несколько правил и перекрытия

Правила независимы и складываются: запрос проходит, если его разрешает любое из них. Порядок правил в списке значения не имеет, приоритетов и «более специфичных» правил нет.

http_filter:
mode: AllowList
rules:
- paths:
- /api/**
methods:
- GET
- paths:
- /api/orders
methods:
- POST

Такая политика разрешает GET на любой путь внутри /api и дополнительно POST /api/orders. При этом POST /api/users заблокирован как неразрешённый метод (путь известен по первому правилу), а DELETE /api/orders — тоже как неразрешённый метод.

Запрещающих правил (deny) в фильтре нет: политика описывается только тем, что разрешено. Чтобы закрыть отдельный путь внутри разрешённого поддерева, нужно не «запретить» его, а сузить разрешение — перечислить нужные поддеревья явно вместо общего **.

Типовые политики

Только чтение всего API:

http_filter:
mode: AllowList
rules:
- paths:
- /api/**
methods:
- GET
- HEAD

Публикация одной версии API, остальные версии закрыты:

http_filter:
mode: AllowList
rules:
- paths:
- /api/v1/**
methods:
- GET
- POST

Коллекция и элемент коллекции с разными правами:

http_filter:
mode: AllowList
rules:
# Коллекция: список и создание.
- paths:
- /api/orders
methods:
- GET
- POST
# Элемент коллекции: чтение и изменение, без удаления.
- paths:
- /api/orders/*
methods:
- GET
- PUT
- PATCH

Приём вебхуков в одну точку и ничего больше:

http_filter:
mode: AllowList
rules:
- paths:
- /hooks/payment
methods:
- POST

Проверка доступности целевого сервиса через контур Netgap:

http_filter:
mode: AllowList
rules:
- paths:
- /health
methods:
- GET

Речь именно о /health целевого сервиса, который вызывается через контур. Точки /health и /metrics самих компонентов Netgap работают на отдельных портах и фильтром не обрабатываются — см. Наблюдаемость.

Частые ошибки

СимптомПричинаЧто сделать
Разрешён /api, но все вложенные пути получают 403Точный путь совпадает только сам с собойИспользовать /api/** (покрывает и /api, и любые вложенные пути)
/api/users/* не пропускает /api/users/42/orders* — ровно один сегментДобавить /api/users/** или отдельный шаблон нужной глубины
Путь с завершающим слэшем получает 403/api и /api/ — разные строки для точного шаблонаПеречислить оба варианта или использовать /api/**
Запросы браузера падают с 405 при разрешённом POSTCORS-preflight отправляет OPTIONS, который не разрешёнДобавить OPTIONS в methods нужного правила
Политика работает на стенде, но на другом контуре всё блокируетсяПути целевого сервиса отличаются регистром или префиксомСверить фактические пути; сопоставление регистрозависимо
Запрос блокируется на исполнителе, хотя шлюз его пропустилПолитики шлюза и исполнителя разошлисьПривести секцию http_filter к одинаковому виду в обеих конфигурациях и перезапустить компоненты
Компонент не стартует с сообщением про '*' внутри сегментаШаблон записан как glob или regex (/api*, /*.json)Использовать подстановку только целым сегментом: * или **

Проверка политики перед вводом в эксплуатацию

Политика применяется целиком при старте, поэтому её проще проверить на стенде, чем «дописывать по инцидентам»:

  1. Соберите фактический список путей и методов, которые используют клиенты (по логам целевого сервиса или существующей интеграции).
  2. Опишите их правилами, начиная с самых узких формулировок; общий /** оставляйте только там, где ограничение действительно не нужно.
  3. Запустите оба компонента с одинаковой политикой и прогоните типовые сценарии клиентов.
  4. Проверьте, что в потоке аудита нет неожиданных событий request blocked by http filter, а метрики блокировок не растут на легитимном трафике — см. Заблокированные запросы.
  5. Переносите политику в промышленный контур одновременно для шлюза и исполнителя; если одновременный перезапуск невозможен, соблюдайте порядок изменения политики.

Ссылки