Глава 44. Порядок обработки и приоритеты¶
43.1. Порядок слоёв¶
Слои обрабатываются в фиксированном порядке. Порядок объявления слоёв в файле политики не влияет на порядок их обработки:
| # | Слой | Назначение |
|---|---|---|
| 1 | <Admin> |
Контроль доступа к управлению |
| 2 | <SSL-Intercept> |
Решение о TLS-инспекции (intercept/tunnel) |
| 3 | <SSL> |
Контроль SSL-параметров (версии, шифры, сертификаты) |
| 4 | <Proxy> |
Основной контроль доступа (allow/deny/auth) |
| 5 | <Waf> |
Детектирование атак, anomaly-скоринг (расширение Redcoat) |
| 6 | <Cache> |
Управление кэшированием |
| 7 | <Forward> |
Маршрутизация (upstream, SOCKS, direct) |
| 8 | <DNS-Proxy> |
Фильтрация и подмена DNS |
| 9 | <SOCKS> |
Контроль SOCKS-соединений |
| 10 | <Exception> |
Кастомизация страниц ошибок; резолвит отложенный deny |
| 11 | <Diagnostics> |
Трассировка и отладка |
43.2. Порядок правил внутри слоя¶
Правила внутри каждого слоя обрабатываются сверху вниз. Срабатывает первое совпавшее правило: все его действия выполняются, оставшиеся правила в текущем слое пропускаются.
<Proxy>
url.domain=example.com allow ; Правило 1 — проверяется первым
url.domain=example.com deny ; Правило 2 — НИКОГДА не сработает для example.com
deny ; Правило 3 — catch-all для остальных
Это означает, что порядок правил критически важен. Более специфичные правила должны стоять выше общих.
Нюанс: несколько действий на один и тот же трафик → одно правило. Так как побеждает только ПЕРВОЕ совпавшее правило, нельзя разносить несколько действий для одного трафика по отдельным безусловным строкам — сработает лишь первое. Объединяйте их в одном правиле:
<Proxy>
; ПРАВИЛЬНО — все три применятся (одно правило, несколько действий):
append(request.header.X-A, "1") set(request.header.X-B, "2") delete(request.header.X-C) allow
; НЕПРАВИЛЬНО — это три отдельных правила, сработает только append:
; append(request.header.X-A, "1")
; set(request.header.X-B, "2")
; delete(request.header.X-C)
Исключение: слои-аккумуляторы. Для слоёв, которые собирают НЕЗАВИСИМЫЕ настройки (а не одно решение allow/deny), применяются ВСЕ совпавшие правила, а не только первое. Это:
<SSL-Intercept>— настройки TLS-перехвата компонуются:ssl.intercept(...),client.certificate.validate(...), ограничения версий/шифров можно задавать отдельными строками, и все они применятся (при конфликте побеждает последняя). См. §28.4.<Waf>— CRS-подобное накопление: множество мелких правил вносят вклад в общий anomaly score.
В остальных слоях (<Proxy>, <SSL>, <Forward>, <Cache>, <Exception> и др.) действует обычная семантика «первое совпавшее правило выигрывает».
43.3. Терминальные vs нетерминальные действия¶
Действия делятся на две категории по влиянию на дальнейшую обработку слоёв:
Терминальные действия — немедленно прерывают обработку оставшихся слоёв:
| Действие | Описание | Особенности |
|---|---|---|
force_deny |
Безусловный отказ | Пропускает Exception-слой |
force_exception |
Безусловная страница ошибки | Пропускает дальнейшую обработку |
deny |
Отказ с возможностью кастомизации | Откладывает отказ и передаёт управление в Exception |
deny.unauthorized |
Отказ с кодом 401 | Терминальный |
exception |
Показ страницы ошибки | Терминальный |
redirect |
HTTP-перенаправление | Терминальный |
authenticate |
Запрос аутентификации | Откладывает запрос аутентификации, если пользователь не аутентифицирован |
rate_limit |
Превышение лимита | Терминальный при срабатывании |
Нетерминальные действия — накапливаются, обработка продолжается к следующему слою:
| Действие | Описание |
|---|---|
allow |
Разрешение запроса |
forward, direct, socks_gateway |
Маршрутизация |
cache, bypass_cache, force_cache, ttl |
Управление кэшированием |
set(request.header.*), delete(request.header.*), append(request.header.*) |
Модификация заголовков запроса |
set(response.header.*), delete(response.header.*), append(response.header.*) |
Модификация заголовков ответа |
log, access_log, label |
Логирование |
log.rewrite.*, log.suppress.* |
Модификация полей логов |
ssl.forward_proxy, ssl.intercept, ssl.verify_server, ssl.verify_client |
TLS-инспекция |
max_bitrate, bandwidth_class, priority |
QoS |
reflect_ip, fail_open |
Параметры forwarding |
socks.authenticate, socks.allowed_versions, socks.allow_bind, socks.allow_udp |
Параметры SOCKS |
dns.server, dns.resolve, dns.cache, dns.ttl, dns.bypass |
Параметры DNS |
trace.* |
Трассировка |
43.4. Механизм pending_deny и Exception¶
При срабатывании deny в слое Proxy происходит не немедленный отказ, а следующий процесс:
- отказ откладывается (ожидающий отказ)
- Обработка продолжается — слой Exception получает управление
- запросу присваивается признак
exception.id=policy_denied - Exception-слой может кастомизировать страницу отказа (шаблон, текст, код ответа)
- Если Exception не совпал — используется стандартная страница отказа
При force_deny — слой Exception пропускается полностью, возвращается стандартная страница.
<Proxy>
category=Malware deny ; pending_deny → Exception получит управление
<Exception>
; Кастомизация страницы для policy_denied
exception.id=policy_denied exception(malware_block_page)
43.5. Таблица числовых приоритетов действий¶
При наличии нескольких действий в одном правиле они сортируются по приоритету (меньшее число = выше приоритет):
| Приоритет | Категория | Действия |
|---|---|---|
| 0 | Force | force_deny |
| 1 | Force | force_exception |
| 5 | Force Auth | authenticate.force (выше deny) |
| 10-19 | Access Control | deny (10), deny.unauthorized (11), exception (12), allow (19) |
| 20-26 | Authentication | authenticate (20), authenticate.mode (21), check_authorization (23) |
| 30-34 | SSL/TLS | ssl.intercept (30), ssl.forward_proxy (31), ssl.verify_server (32), ssl.verify_client (33) |
| 40-48 | Forwarding | forward (40), direct (41), socks_gateway (42), fail_open (47), reflect_ip (48) |
| 50-56 | Caching | force_cache (50), cache (51), bypass_cache (52), ttl (53) |
| 60-68 | Modification | redirect (60), rewrite (61), set (62), заголовки запроса (63-65), заголовки ответа (66-68) |
| 70-73 | QoS | rate_limit (70), max_bitrate (71), bandwidth_class (72), priority (73) |
| 80-88 | DNS | dns.respond (80), dns.respond.a (81), dns.respond.aaaa (82), dns.respond.ptr (83), dns.server (84), dns.bypass (88) |
| 90-98 | Logging | log (90), access_log (91), log.rewrite (92), log.suppress (93), label (94), trace.* (95-98) |
43.6. Ключевые правила разрешения конфликтов¶
deny vs authenticate:
- deny имеет приоритет 10, authenticate — приоритет 20
- В правиле authenticate(realm) deny — отказ выполнится до запроса аутентификации (пользователь не увидит промпт)
- Для обратного поведения: authenticate.force(realm) (приоритет 5) — аутентификация выполнится до deny
force_deny vs всё:
- force_deny (приоритет 0) побеждает абсолютно всё
- Пропускает Exception-слой — кастомизация невозможна
- Используйте для санкционных ограничений, критических блокировок
Последнее значение для одного свойства:
- При конфликте одноимённых действий (cache(yes) cache(no)) побеждает последнее
- При конфликте взаимоисключающих (forward + direct) генерируется предупреждение, побеждает последнее
43.7. Взаимодействие слоёв¶
Admin → остальные слои:
- Если Admin разрешает доступ (admin.access(read-write)), управление передаётся на API обработки
- Если Admin не совпал — запрос обрабатывается как обычный прокси-трафик
SSL-Intercept → Proxy: - Решение о MITM (intercept/tunnel) определяет, какие условия доступны в Proxy - При tunnel (no intercept) — доступны только SNI, IP, порт, GeoIP - При intercept — доступны все условия (URL, заголовки, тело, категория)
Proxy → Exception:
- deny устанавливает pending_deny и передаёт в Exception для кастомизации
- force_deny — Exception пропускается полностью
Forward → upstream:
- Нетерминальные результаты Forward (forward, socks_gateway, direct) определяют маршрут соединения
- fail_open(yes) определяет поведение при недоступности upstream
Все слои → Diagnostics:
- Diagnostics работает независимо от других слоёв
- Трассировка (trace.*) накапливается со всех слоёв