Правила фильтра: пути и методы
Правило — это связка «вот пути, вот разрешённые для них методы». Пути в правиле первичны: сначала выбираются правила, чьи шаблоны совпали с путём запроса, затем среди них проверяется метод.
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-preflightOPTIONS, эти методы нужно перечислить явно. - В 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 при разрешённом POST | CORS-preflight отправляет OPTIONS, который не разрешён | Добавить OPTIONS в methods нужного правила |
| Политика работает на стенде, но на другом контуре всё блокируется | Пути целевого сервиса отличаются регистром или префиксом | Сверить фактические пути; сопоставление регистрозависимо |
| Запрос блокируется на исполнителе, хотя шлюз его пропустил | Политики шлюза и исполнителя разошлись | Привести секцию http_filter к одинаковому виду в обеих конфигурациях и перезапустить компоненты |
Компонент не стартует с сообщением про '*' внутри сегмента | Шаблон записан как glob или regex (/api*, /*.json) | Использовать подстановку только целым сегментом: * или ** |
Проверка политики перед вводом в эксплуатацию
Политика применяется целиком при старте, поэтому её проще проверить на стенде, чем «дописывать по инцидентам»:
- Соберите фактический список путей и методов, которые используют клиенты (по логам целевого сервиса или существующей интеграции).
- Опишите их правилами, начиная с самых узких формулировок; общий
/**оставляйте только там, где ограничение действительно не нужно. - Запустите оба компонента с одинаковой политикой и прогоните типовые сценарии клиентов.
- Проверьте, что в потоке аудита нет неожиданных событий
request blocked by http filter, а метрики блокировок не растут на легитимном трафике — см. Заблокированные запросы. - Переносите политику в промышленный контур одновременно для шлюза и исполнителя; если одновременный перезапуск невозможен, соблюдайте порядок изменения политики.
Ссылки
- Конфигурирование фильтра HTTP-запросов — секция
http_filter, режимы, проверка конфигурации при старте. - Заблокированные запросы: ответ, аудит и метрики — что видит клиент и что видит оператор.
- Схемы размещения фильтра: шлюз, исполнитель или оба — где включать
AllowListи в каком порядке раскатывать изменения. - Конфигурирование приложения — как передать YAML-документ в компонент.