Firewall
Firewall позволяет описать, какие запросы к проекту нужно пропустить, заблокировать, записать в лог или ограничить по частоте. Правила проверяются до обработки запроса приложением и до дополнительных защит preview-деплоев.
Когда использовать Firewall
Заголовок раздела «Когда использовать Firewall»Используйте Firewall, когда нужно управлять входящим трафиком к проекту:
| Задача | Как решается |
|---|---|
Закрыть /admin или внутренний раздел | Правило по request.path и IP/CIDR офиса |
| Разрешить доступ только из офисной сети | defaultAction: deny и allow-правило для нужных CIDR |
| Ограничить доступ из стран или регионов | Правило по geo.country или geo.continent |
| Найти подозрительные запросы перед блокировкой | log-правило и режим shadow |
| Ограничить частоту запросов к API или разделу | rate_limit-правило по IP, path или host |
Firewall не заменяет маршрутизацию, домены и Preview Protection. Для redirects, rewrites и HTTP-заголовков используйте Правила маршрутизации. Для логина, пароля и bypass-токенов preview-деплоев используйте Preview Protection.
Где находится
Заголовок раздела «Где находится»-
Откройте нужный проект.
-
Перейдите в Project → Firewall.
-
Настройте режим, действие по умолчанию и правила. Для сложных правил используйте Advanced JSON config.
-
Сохраните черновик.
-
Проверьте черновик через симулятор и события.
-
Опубликуйте политику.
На уровне workspace страница Firewall показывает обзор проектов и ссылки на проектные политики. Сами правила редактируются в проекте.
Как запрос проходит через защиты
Заголовок раздела «Как запрос проходит через защиты»Firewall применяется до приложения, но он не единственная проверка запроса:
- Платформенные защиты ONREZA от очевидно вредного трафика.
- Пользовательская политика Firewall проекта.
- Preview Protection, если запрос идёт к защищённому preview-деплою.
- Приложение и его middleware.
Важно: действие allow разрешает запрос только с точки зрения пользовательского Firewall. Оно не отключает платформенные защиты и не обходит Preview Protection.
Режимы работы
Заголовок раздела «Режимы работы»| Режим | Что происходит | Когда использовать |
|---|---|---|
shadow | ONREZA считает, какое действие сработало бы, и показывает это в событиях. Ответ пользователю не меняется. | При создании и проверке новых правил. |
enforce | deny, defaultAction: deny и превышенные rate_limit-правила начинают менять HTTP-ответ. | После проверки симулятором и событиями. |
В enforce ONREZA предупреждает перед публикацией опасных вариантов: defaultAction: deny, включённых deny-правил и правил rate_limit.
Быстрый пример
Заголовок раздела «Быстрый пример»Dashboard публикует canonical JSON config. YAML ниже — удобный authoring-формат для файлов, редакторов и LLM; перед публикацией перенесите его в canonical JSON config.
# yaml-language-server: $schema=https://docs.onreza.ru/schemas/firewall-policy-v1.schema.jsonschemaVersion: 1mode: shadowdefaultAction: allow
rules: - id: block-admin-outside-office name: Block admin outside office enabled: true action: type: deny statusCode: 403 when: any: - all: - field: request.path op: prefix value: /admin - field: client.ip op: not_in_cidr values: - 203.0.113.0/24Та же политика в Advanced JSON config:
{ "mode": "SHADOW", "defaultAction": "ALLOW", "rules": [ { "id": "block-admin-outside-office", "name": "Block admin outside office", "enabled": true, "position": 0, "conditionGroups": [ { "conditions": [ { "field": "request.path", "op": "prefix", "value": "/admin" }, { "field": "client.ip", "op": "not_in_cidr", "values": ["203.0.113.0/24"] } ] } ], "action": { "type": "DENY", "statusCode": 403 } } ]}Mapping из YAML в JSON прямой: when.any[] становится conditionGroups[], all[] становится conditions[], порядок rules[] превращается в position, а mode, defaultAction и action.type в JSON пишутся в верхнем регистре.
Эта политика говорит: если путь начинается с /admin и IP не входит в офисный CIDR, запрос будет заблокирован. В режиме shadow ONREZA только покажет в симуляторе и логах, что запрос был бы заблокирован.
JSON Schema
Заголовок раздела «JSON Schema»Машинно-читаемая схема доступна по стабильному URL:
https://docs.onreza.ru/schemas/firewall-policy-v1.schema.jsonИспользуйте её в YAML-файле, чтобы редакторы и LLM видели полный authoring-контракт:
# yaml-language-server: $schema=https://docs.onreza.ru/schemas/firewall-policy-v1.schema.jsonКак читается политика
Заголовок раздела «Как читается политика»schemaVersion: 1mode: shadowdefaultAction: allowrules: []| Поле | Что означает |
|---|---|
schemaVersion | Версия authoring-формата YAML. Сейчас 1. |
mode | shadow проверяет без блокировки, enforce применяет действия. |
defaultAction | Что делать, если ни одно правило не сработало: allow или deny. |
rules | Список правил сверху вниз. |
Правила проверяются по порядку. Порядок элементов в rules сохраняется при публикации, поэтому первое совпавшее терминальное действие выигрывает. Если правило выключено (enabled: false), оно пропускается. Если enabled не указан, правило считается включенным.
Черновик, публикация и откат
Заголовок раздела «Черновик, публикация и откат»Изменения Firewall проходят через черновик. Это защищает проект от случайного применения незавершённых правил.
| Состояние | Что означает |
|---|---|
| Черновик | Изменения сохранены, но ещё не влияют на опубликованную политику. |
| Опубликованная версия | Версия, которую ONREZA использует для новых запросов. |
| Discard draft | Удаляет черновик и возвращает редактор к опубликованной версии. |
| Rollback | Возвращает предыдущую опубликованную версию, если новая политика работает не так, как ожидалось. |
Если вы публикуете enforce-политику с блокирующими действиями, интерфейс попросит подтвердить публикацию. Это ожидаемая защита от случайной блокировки трафика.
События Firewall
Заголовок раздела «События Firewall»После публикации политики страница проекта показывает последние решения Firewall и краткую сводку:
| Показатель | Что помогает понять |
|---|---|
| Total | Сколько решений попало в текущую выборку. |
| Would block | Сколько запросов было бы заблокировано в shadow. |
| Blocked | Сколько запросов реально заблокировано в enforce. |
| Rate limited | Сколько запросов попало под ограничение частоты или было бы ограничено. |
| Top rules | Какие правила срабатывают чаще всего. |
Используйте события так:
- Опубликуйте политику в
shadow. - Дождитесь реального трафика или проверьте запросы вручную.
- Посмотрите, какие правила сработали и какие запросы получили бы блокировку.
- Если результат ожидаемый, переключайте политику в
enforce.
Логика any/all
Заголовок раздела «Логика any/all»У каждого правила есть блок when:
when: any: - all: - field: request.path op: prefix value: /admin - field: request.method op: equals value: POST - all: - field: ua.raw op: contains value: curlЭто читается так:
any— правило сработает, если совпала хотя бы одна группа.all— внутри группы должны совпасть все условия.- Несколько групп в
anyработают какOR. - Несколько условий в
allработают какAND.
Поля условий
Заголовок раздела «Поля условий»| Поле | Примеры |
|---|---|
client.ip | IP или CIDR: 203.0.113.10, 203.0.113.0/24 |
geo.country | ISO-код страны: DE, US, RU |
geo.continent | Континент: EU, AS, NA |
request.host | app.example.com |
request.path | /admin, /api |
request.method | GET, POST, DELETE |
request.header | HTTP-заголовок по key |
request.cookie | Cookie по key |
request.query | Query-параметр по key |
ua.raw | Исходный User-Agent |
ua.browser | Название браузера |
ua.device | desktop, mobile, tablet |
Для request.header, request.cookie и request.query укажите key:
- field: request.header key: x-api-client op: equals value: mobileОператоры
Заголовок раздела «Операторы»| Оператор | Когда использовать |
|---|---|
equals, not_equals | Точное сравнение |
in, not_in | Значение входит или не входит в список |
contains, not_contains | Строка содержит подстроку |
prefix, suffix | Путь, host или строка начинается/заканчивается на значение |
regex, not_regex | Регулярное выражение |
exists, not_exists | Поле существует или отсутствует; чаще всего используется для заголовков, cookie и query-параметров |
in_cidr, not_in_cidr | Только для client.ip |
Для request.header, request.cookie и request.query один ключ может встретиться несколько раз. Если правило защищает доступ к чувствительному endpoint, безопаснее описывать позитивный allow-list (equals или in) вместе с defaultAction: deny, а не строить доступ на not_*-условиях для повторяемых ключей.
Действия
Заголовок раздела «Действия»action: type: logЗаписывает совпадение и продолжает проверять следующие правила.
action: type: allowРазрешает запрос с точки зрения пользовательского Firewall. Это не обходит Preview Protection и платформенные защиты.
action: type: deny statusCode: 403Блокирует запрос кодом 403 в режиме enforce. Если statusCode не указан, используется 403.
action: type: rate_limit limit: 120 windowSeconds: 60 key: ip_pathОграничивает частоту запросов. Если key не указан, используется ip. В режиме enforce запросы сверх лимита получают 429 Too Many Requests и заголовок Retry-After.
Ключ определяет, что именно считается отдельным счётчиком:
| Key | Счётчик |
|---|---|
ip | Один счётчик на IP. |
ip_path | Отдельный счётчик на пару IP + path. |
ip_host | Отдельный счётчик на пару IP + host. |
host | Один счётчик на host, общий для всех IP. |
Примеры
Заголовок раздела «Примеры»Блокировать /admin вне офисной сети
Заголовок раздела «Блокировать /admin вне офисной сети»schemaVersion: 1mode: shadowdefaultAction: allow
rules: - id: block-admin-outside-office name: Block admin outside office enabled: true action: type: deny statusCode: 403 when: any: - all: - field: request.path op: prefix value: /admin - field: client.ip op: not_in_cidr values: - 203.0.113.0/24Блокировать страну для всего проекта
Заголовок раздела «Блокировать страну для всего проекта»schemaVersion: 1mode: shadowdefaultAction: allow
rules: - id: block-country name: Block country enabled: true action: type: deny statusCode: 403 when: any: - all: - field: geo.country op: in values: [RU]Разрешить только офисную сеть
Заголовок раздела «Разрешить только офисную сеть»Этот сценарий использует defaultAction: deny: всё, что не совпало с allow-правилом, будет заблокировано после публикации в enforce.
schemaVersion: 1mode: shadowdefaultAction: deny
rules: - id: allow-office-network name: Allow office network enabled: true action: type: allow when: any: - all: - field: client.ip op: in_cidr values: - 203.0.113.0/24Записывать подозрительный User-Agent
Заголовок раздела «Записывать подозрительный User-Agent»schemaVersion: 1mode: shadowdefaultAction: allow
rules: - id: log-cli-user-agents name: Log CLI user agents enabled: true action: type: log when: any: - all: - field: ua.raw op: contains value: curlОграничить API по IP и пути
Заголовок раздела «Ограничить API по IP и пути»schemaVersion: 1mode: shadowdefaultAction: allow
rules: - id: rate-limit-api name: Rate limit API enabled: true action: type: rate_limit limit: 120 windowSeconds: 60 key: ip_path when: any: - all: - field: request.path op: prefix value: /apiВ shadow события покажут would_rate_limit, когда запрос превысил бы лимит. В enforce такой запрос получит 429.
Проверка перед публикацией
Заголовок раздела «Проверка перед публикацией»-
Откройте Project → Firewall.
-
Соберите простое правило preset-кнопками или откройте Advanced JSON config для полного canonical config.
-
Если используете YAML как authoring-формат, проверьте его по JSON Schema и соберите эквивалентный canonical JSON config по mapping выше. Затем сохраните черновик.
-
Проверьте политику через симулятор: укажите IP, path, method, country и headers.
-
Сначала опубликуйте в
shadow. -
Откройте события Firewall и проверьте
would blockиwould rate limitна реальном трафике. -
Если результат ожидаемый, переключите
modeнаenforceи опубликуйте снова. -
Подтвердите публикацию, если интерфейс предупреждает о блокирующих действиях.
Что проверить перед enforce
Заголовок раздела «Что проверить перед enforce»Перед публикацией политики, которая может блокировать запросы, проверьте список:
| Проверка | Почему важно |
|---|---|
| Симулятор показывает ожидаемое правило | Так проще поймать ошибку в path, CIDR, country или header. |
В событиях нет неожиданных would block или would rate limit | Реальный трафик может отличаться от тестового запроса. |
Для defaultAction: deny есть нужные allow-правила | Иначе проект может закрыться для всех посетителей. |
Для rate_limit выбран правильный key | host ограничивает всех посетителей вместе, а ip_path обычно безопаснее для API. |
| Preview Protection настроен отдельно | Firewall allow не является preview bypass. |
| Есть план отката | При ошибке нужно быстро вернуться к предыдущей опубликованной версии. |
Если после публикации трафик заблокирован или ограничен
Заголовок раздела «Если после публикации трафик заблокирован или ограничен»-
Откройте Project → Firewall.
-
Посмотрите последние события и найдите правило, которое вернуло
blockedилиrate_limited. -
Если блокировка ошибочная, верните предыдущую опубликованную версию или переключите политику в
shadowи опубликуйте. -
Исправьте черновик и проверьте его через симулятор.
-
Опубликуйте исправленную версию только после проверки событий.
Ограничения текущей версии
Заголовок раздела «Ограничения текущей версии»| Ограничение | Что это значит |
|---|---|
| Rate limit локальный для edge-узла | Лимит применяется быстро и без внешнего запроса, но не является точным глобальным лимитом по всем edge-узлам. |
| Визуальный редактор покрывает пресеты | Для allow, log, rate_limit, headers, cookies, query, geo и User-Agent используйте Advanced JSON config. |
| Нет проверки тела запроса | Firewall работает с IP, geo, host, path, method, headers, cookies, query и User-Agent. |
| Geo и User-Agent не являются личностью пользователя | VPN, прокси и подмена User-Agent могут менять результат. |
allow не является bypass | Запрос всё равно проходит Preview Protection и платформенные защиты. |
| Routing Rules остаются отдельно | Firewall не делает redirects, rewrites и не управляет HTTP-заголовками ответа. |
Если вам нужно ограничить доступ к preview-деплою по логину, паролю или bypass-токену, используйте Preview Protection. Если нужно изменить путь, домен или заголовки ответа, используйте Правила маршрутизации.
Что дать LLM
Заголовок раздела «Что дать LLM»Скопируйте этот промпт и замените сценарий на свой:
Ты генерируешь YAML-политику ONREZA Firewall.Используй только schemaVersion: 1 и JSON Schema:https://docs.onreza.ru/schemas/firewall-policy-v1.schema.json
Требования:- mode должен быть shadow, если я явно не прошу enforce.- defaultAction обычно allow, если я явно не прошу default deny.- Используй стабильные rule id в kebab-case.- Не используй JavaScript, язык выражений или поля вне схемы.- После YAML кратко объясни, какие запросы совпадут с правилами.
Сценарий:<опишите, что нужно заблокировать или разрешить>См. также
Заголовок раздела «См. также»- Preview Protection — логин, пароль и bypass для preview-деплоев.
- Правила маршрутизации — redirects, rewrites и HTTP-заголовки.
- JSON Schema — полный машинно-читаемый контракт.