Глава 23. Дополнительные условия¶
Условия этой главы покрывают прочие аспекты транзакции, не вошедшие в предыдущие главы: определение режима прокси (transparent vs explicit) и пользовательские атрибуты.
23.1. is_transparent=¶
Проверяет, было ли соединение клиента перехвачено через transparent proxy (без явной настройки прокси на клиенте). Transparent proxy перехватывает трафик на сетевом уровне с помощью SO_ORIGINAL_DST или аналогичных механизмов.
Статус: планируется. Использование в CPL файле приведёт к ошибке парсинга.
Аналог в BlueCoat:
tunneled=(BlueCoat) — проверяет, является ли транзакция туннелированной (CONNECT). Условиеis_transparent=в Redcoat проверяет другой аспект: способ подключения клиента к прокси, а не тип HTTP-транзакции.
Синтаксис:
where:
yes— соединение перехвачено через transparent proxy.no— клиент подключён не через transparent interception.
Слои и транзакции: Proxy.
Пример:
<Proxy>
; Для transparent-клиентов — показать captive portal
is_transparent=yes session.has_valid_session=no redirect(302, "https://portal.corp.local/")
; Разные правила для transparent и explicit
is_transparent=yes category=Streaming deny
См. также: is_explicit= (раздел 23.2), proxy.port= (глава 7).
23.2. is_explicit=¶
Проверяет, подключился ли клиент к прокси через явную (explicit) настройку — клиент осознанно настроен на использование прокси-сервера (через системные настройки, PAC-файл или переменные окружения).
Статус: планируется. Использование в CPL файле приведёт к ошибке парсинга.
Синтаксис:
where:
yes— клиент подключён через explicit proxy.no— клиент подключён не через explicit proxy.
Слои и транзакции: Proxy.
Пример:
<Proxy>
; Explicit-клиентам доступна полная аутентификация
is_explicit=yes authenticate(corporate_realm)
; Блокировать SOCKS через explicit proxy
is_explicit=yes socks.version=5 deny
См. также: is_transparent= (раздел 23.1).
23.3. Атрибуты пользователя (attribute.*)¶
Проверяет атрибуты аутентифицированного пользователя, полученные из LDAP-директории или RADIUS-ответа при аутентификации. Атрибуты загружаются автоматически при успешной аутентификации — все атрибуты из LDAP-записи пользователя становятся доступны для условий политики.
Совместимость: BlueCoat
attribute.name=(C-002 в матрице Layer Support).
Синтаксис:
where:
<name>— имя LDAP/RADIUS атрибута (например,department,title,Service-Type). Регистрозависимо.<value>— ожидаемое значение атрибута. Можно использовать кавычки для значений с пробелами:attribute.title="Senior Developer".has_attribute.<name>=yes— проверяет только наличие атрибута (без проверки значения).- Поддерживается отрицание:
attribute.<name>!=valueиhas_attribute.<name>=no.
Слои и транзакции: Proxy, Cache, Forward, SSL, SSL-Intercept, Admin, DNS-Proxy, Exception, Diagnostic.
Источник атрибутов:
| Backend | Источник | Пример атрибутов |
|---|---|---|
| LDAP | Запись пользователя (objectClass=*) |
departmentNumber, title, mail, employeeType |
| RADIUS | Access-Accept ответ | Service-Type, Filter-Id (планируется) |
Примеры:
<Proxy>
authenticate(LDAPRealm)
<Proxy>
; Разрешить только инженерам
attribute.departmentNumber=Engineering ALLOW
deny
; Блокировать по уровню риска
attribute.risk_level=high deny
; Проверка наличия атрибута
has_attribute.vpn_connected=yes ALLOW
Производительность: Атрибуты загружаются из LDAP одним дополнительным запросом при аутентификации. Условие attribute.* проверяется после индексного сопоставления, дополнительные затраты — около 50 нс.
Кеширование атрибутов: Атрибуты сохраняются в кеше аутентификации и IP-суррогате. При попадании в кеш или суррогат атрибуты автоматически восстанавливаются. IP-суррогат очищается при установке новой политики. При наличии заголовка Proxy-Authorization с другим именем пользователя суррогат пропускается, и учётные данные перепроверяются.
23.4. LDAP-атрибуты (ldap.attribute.*)¶
Специализированные формы проверки атрибутов LDAP-директории. В отличие от общего attribute.<name>= (раздел 23.3), эти формы позволяют проверять наличие атрибута, сравнивать его как число и проверять количество значений. Используют тот же источник — state.user_attributes, загружаемый при LDAP-аутентификации.
Совместимость: BlueCoat
ldap.attribute.<name>=,.exists=,.as_number=,.count=.
Синтаксис:
ldap.attribute.<name>=<value> ; сравнение значения (exact/wildcard/list)
ldap.attribute.<name>.exists=yes|no ; наличие атрибута
ldap.attribute.<name>.as_number=<range> ; значение как число (N, N..M, >N, <N)
ldap.attribute.<name>.count=<range> ; количество значений атрибута
Примеры:
<Proxy>
authenticate(LDAPRealm)
; Сравнение значения
ldap.attribute.department=Engineering allow
; Наличие атрибута
ldap.attribute.mail.exists=yes allow
; Числовое сравнение (employeeID в диапазоне)
ldap.attribute.employeeID.as_number=1000..9999 allow
; Количество значений (членство хотя бы в одной группе)
ldap.attribute.memberOf.count=1 allow
deny
where:
<name>— имя LDAP-атрибута. Регистрозависимо..exists=yes|no— проверяет наличие атрибута в записи пользователя..as_number=<range>— значение атрибута парсится как целое (u64) и сравнивается с диапазоном. Если значение не число — условие не срабатывает..count=<range>— количество значений атрибута.
Ограничение: одно значение на атрибут
Текущее хранилище атрибутов содержит одно значение на имя атрибута. Поэтому ldap.attribute.<name>.count= возвращает 0 (атрибут отсутствует) или 1 (присутствует). Полноценная поддержка многозначных LDAP-атрибутов будет добавлена позже.
Слои: Proxy, Cache, Forward, SSL, SSL-Intercept, Admin, Exception, Diagnostic. Условие проверяется после индексного сопоставления.
См. также: attribute.*, has_attribute.* (раздел 23.3).
authenticate() + deny — приоритеты (CPL Reference 7.3):
denyимеет более высокий приоритет, чемauthenticate()(«Deny has precedence over authentication… does not depend on the order of the layers», CPL Ref 7.3). Поэтому если в слое естьauthenticate(realm)иdeny(любой — catch-all или условный), который применяется, неаутентифицированный пользователь получает отказ (403/exception) БЕЗ challenge. Имя пользователя при этом не попадёт в access log.- Чтобы гарантированно выдать challenge ПЕРЕД deny (например, ради логирования user id для отклонённых запросов), используйте
authenticate.force(realm)(force_authenticate) — у него приоритет ВЫШЕdeny. Тогда неаутентифицированный пользователь сначала получит challenge, аутентифицируется, и лишь потом применится deny/allow.
Тип challenge зависит от Authentication Mode (не от политики): proxy* → 407 Proxy-Authenticate (клиент отвечает Proxy-Authorization); origin* → 401 WWW-Authenticate (клиент отвечает Authorization, OCS-style); form* → 302 redirect на captive-portal.
Пример (challenge-first через force):
<Proxy>
authenticate.force(LdapRealm) ; приоритет выше deny → challenge ПЕРВЫМ
authenticated=yes ALLOW
DENY ; применится только после аутентификации
</Proxy>
force (authenticate(LdapRealm) + DENY) неаутентифицированный запрос был бы отклонён сразу (403), не увидев challenge.
См. также: user= (глава 12), group= (глава 12), authenticated= (12.1).
23.4a. SAML-атрибуты (saml.attribute.*)¶
Проверяет значение атрибута из SAML-assertion, полученного при аутентификации в SAML realm. Аналог ldap.attribute.* (раздел 23.4), но источник данных — атрибуты SAML-утверждения (assertion attributes), а не запись LDAP-директории.
Совместимость: BlueCoat
saml.attribute.<attribute_name>=.
Синтаксис:
где:
<attribute_name>— имя атрибута SAML-assertion;pattern— значение для сравнения (точное совпадение, wildcard или список);string_modifier— модификатор строкового сравнения (необязателен), как у прочих строковых условий;case_sensitive— признак учёта регистра при сравнении (необязателен).
Примеры:
<Proxy>
authenticate(SAMLRealm)
; Доступ по значению атрибута департамента из SAML-assertion
saml.attribute.department=Engineering allow
deny
Слои: Proxy, Cache, Forward, SSL, SSL-Intercept, Admin, Exception, Diagnostic.
См. также: LDAP-атрибуты ldap.attribute.* (23.4), attribute.* (23.3), realm= (12.5).
23.3a. Битрейт потокового видео (bitrate=)¶
Проверяет битрейт потокового видео (HLS/DASH), определённый из манифеста. Прокси автоматически парсит HLS master playlist (.m3u8) и DASH MPD (.mpd), извлекает доступные варианты битрейта и кеширует соответствие URL→битрейт. При последующих запросах за сегменты видео, условие bitrate= сопоставляет битрейт запрошенного варианта.
Совместимость: BlueCoat
bitrate=(C-004 в матрице Layer Support). В BlueCoat поддерживает RTSP/MMS/RTMP — в Redcoat поддерживаются HTTP-based протоколы: HLS и DASH.
Синтаксис:
where: значения в битах в секунду. Суффиксы: k = ×1000, m = ×1000000, g = ×1000000000. Примеры: 56k = 56000 bps, 2m = 2000000 bps, 1g = 1000000000 bps.
Слои и транзакции: Proxy, Cache.
Как работает:
- Клиент запрашивает HLS master playlist через прокси
- Прокси парсит ответ, извлекает
BANDWIDTH=из#EXT-X-STREAM-INF - Кеширует соответствие URL variant → битрейт (TTL 5 мин)
- При запросе сегмента видео — определяет битрейт из кеша
- CPL правило
bitrate=проверяет этот битрейт
Примеры:
<Proxy>
; Запретить потоковое видео выше 2 Mbps
bitrate=2000001..999999999 deny
ALLOW
; Разрешить группе VIP до 10 Mbps, остальным до 1 Mbps
group=VIP bitrate=10000001..999999999 deny
bitrate=1000001..999999999 deny
ALLOW
Производительность: Нулевые затраты для не-потокового трафика (одна проверка Content-Type). Для потокового: около 50 нс на поиск по таблице при каждом запросе сегмента. Разбор манифеста: менее 0,1 мс (один раз при первом запросе).
Поддерживаемые форматы:
| Формат | Content-Type | Расширение | Парсинг |
|---|---|---|---|
| HLS Master Playlist | application/vnd.apple.mpegurl |
.m3u8 |
#EXT-X-STREAM-INF:BANDWIDTH= |
| DASH MPD | application/dash+xml |
.mpd |
<Representation bandwidth="..."> |
См. также: max_bitrate() (глава 32) — ограничение скорости передачи (throttle).
23.3b. Прочие потоковые условия (streaming.*)¶
Статус: в процессе реализации. Условия
streaming.rtmp.*принимаются парсером (имена как в BlueCoat, политика загружается), но разбор протокола RTMP отсутствует — данные не заполняются, правило с ними не сработает.
streaming.rtmp.app_name=имя
streaming.rtmp.method=метод
streaming.rtmp.page_url=url
streaming.rtmp.stream_name=имя
streaming.rtmp.swf_url=url
Условия
streaming.client=иstreaming.content=(BlueCoat) парсером не принимаются (использование приведёт к ошибке загрузки политики). Для HTTP-стриминга используйтеlive=(раздел 9.12) иbitrate=(раздел 23.3a).
23.4. Условия X-Forwarded-For¶
Проверяет наличие и значение заголовка X-Forwarded-For (используется при каскадировании прокси). Эти условия реализуются через общие условия заголовков (глава 10) и не требуют отдельного парсера.
Синтаксис:
Слои и транзакции: Proxy.
Пример:
<Proxy>
; Проверить наличие заголовка (каскадный прокси)
request.header.X-Forwarded-For.exists=yes log.header.x-forwarded("true")
; Проверить адрес в X-Forwarded-For
request.header.X-Forwarded-For.address=10.0.0.0/8 ALLOW
См. также: request.header.* (глава 10), client.address= (глава 7).
23.x. Условия классификации приложений (request.application.*)¶
Статус: в процессе реализации. Движок классификации приложений отсутствует.
request.application.name=иrequest.application.operation=принимаются парсером, но правило с ними не сработает. Формыrequest.application.group=иrequest.application.attribute=(имена BlueCoat) парсером пока не принимаются; ближайшие принимаемые варианты —request.application.type=иrequest.application.behavior=(также в процессе реализации).
Группа условий для политик по веб-приложениям (имена как в BlueCoat):
23.5. random= — вероятностная выборка¶
Условие вероятностной выборки: для каждого правила условие истинно приблизительно 1 раз из n (вероятность 1/n). Используется в сочетании с другими условиями — чтобы применить действие (трассировку, логирование, выборочную инспекцию) не ко всем подходящим транзакциям, а к их случайной доле. Например, random=10 совпадает примерно для 10 % транзакций, random=100 — для 1 %.
Семантика как в BlueCoat 7.3. «n: The condition evaluates to true approximately 1/n times for the policy rule.»
Синтаксис:
where:
n— условие истинно приблизительно1/nраз (чем большеn, тем реже совпадение).
Слои и транзакции: все прокси-транзакции.
Пример:
<Diagnostics>
; Трассировать случайную выборку GET-запросов
http.method=GET random=10 trace.request(yes)
См. также: trace.request() (34.1), условия времени (глава 14).
23.6. admin.access=¶
Проверяет тип (уровень) административного доступа в текущей управляющей транзакции. Используется в слое <Admin> для разграничения политик чтения и записи при доступе к управлению прокси.
Имя как в BlueCoat. Реализованы оба смысла: условие
admin.access=(проверка) и действиеadmin.access(read-write)(установка уровня доступа, см. приложение A.1).
Синтаксис:
where:
read— доступ только на чтение (просмотр конфигурации/состояния);write— доступ на запись (изменение конфигурации).
Слои и транзакции: <Admin>.
Пример:
<Admin>
; Операции записи разрешить только администраторам
admin.access=write group=Administrators allow
admin.access=write deny
; Чтение разрешено всем аутентифицированным
admin.access=read authenticated=yes allow
См. также: слой <Admin> (4.10), authenticated= (12.1), group= (12.4), приложение A.1.