Глава 27. Аутентификация¶
Действия аутентификации управляют проверкой подлинности пользователей. Когда срабатывает authenticate(realm), прокси возвращает клиенту запрос аутентификации: HTTP 407 Proxy-Authenticate для explicit proxy или HTTP 401 WWW-Authenticate для transparent/origin режимов.
Аутентификация в Redcoat интегрирована в CPL-слой и выполняется в три фазы:
1. Извлечение учётных данных — парсинг заголовка Proxy-Authorization / Authorization, проверка IP/cookie surrogate, валидация учётных данных.
2. Оценка CPL — правила могут вернуть authenticate(realm) (требуется аутентификация) или authenticate(no) (аутентификация отключена).
3. Формирование challenge — генерация ответа 407/401 с заголовком Proxy-Authenticate / WWW-Authenticate.
27.1. authenticate()¶
Свойство authenticate() требует аутентификацию пользователя через указанный realm (область аутентификации). Realm определяет, какой backend используется для проверки учётных данных (LDAP, RADIUS, локальные пользователи и т.д.).
Если пользователь уже аутентифицирован в указанном realm (через заголовок, IP surrogate или cookie surrogate), действие пропускается и обработка продолжается. Если пользователь не аутентифицирован, прокси возвращает challenge (407/401) и ожидает повторный запрос с учётными данными.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
realm_name |
Строка | Имя realm, настроенного в конфигурации прокси. Определяет backend аутентификации и его параметры. |
Тип: Терминальное (условно). Если пользователь не аутентифицирован — обработка прекращается, клиенту возвращается 407/401. Если уже аутентифицирован — действие пропускается (нетерминальное поведение).
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример 1. Обязательная аутентификация:
Пример 2. Аутентификация с исключениями:
<Proxy>
url.path=/health authenticate(no) allow
url.path=/api/public authenticate(no) allow
authenticate(Corporate_Realm)
group=Admins allow
group=Users category=!Malware allow
deny
См. также: authenticate(no), authenticate.force(), authenticate.realm(), check_authorization
27.2. authenticate(no)¶
Свойство authenticate(no) явно отключает требование аутентификации для совпавшего запроса. Запрос пропускается без проверки учётных данных, даже если другие правила в том же слое требуют аутентификацию.
Синтаксис:
Тип: Нетерминальное. Устанавливает флаг отключения аутентификации для текущего запроса. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
<Proxy>
; Health check и публичные API не требуют аутентификации
url.path=/health authenticate(no) allow
url.path=/api/public/(.*) authenticate(no) allow
; Всё остальное — через LDAP
authenticate(LDAP_Realm)
См. также: authenticate(), authenticate.force()
27.3. authenticate.force()¶
Важно. Свойство принимается, но пока не применяется: значение сохраняется, однако повторный challenge по нему не выдаётся. Не полагайтесь на
authenticate.force()как на гарантию повторной аутентификации — поведение пока эквивалентно обычномуauthenticate().
Свойство authenticate.force() принудительно запрашивает повторную аутентификацию, даже если пользователь уже аутентифицирован в указанном realm. Текущая сессия аутентификации инвалидируется.
В BlueCoat CPL authenticate.force() имеет приоритет выше deny — это позволяет принудительно запросить учётные данные перед отклонением запроса. Используется для сценариев смены пароля, повышенной безопасности для критичных ресурсов и повторной проверки при подозрении на компрометацию сессии.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
realm_name |
Строка | Имя realm для принудительной аутентификации. |
Тип: Терминальное. Всегда возвращает challenge (407/401), независимо от текущего состояния аутентификации.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример 1. Принудительная аутентификация для критичных ресурсов:
Пример 2. Повторная аутентификация при доступе к финансовым данным:
См. также: authenticate(), authenticate(no), authenticate.realm()
27.4. authenticate.mode()¶
Свойство authenticate.mode() определяет способ передачи и хранения учётных данных для данной транзакции. Режим влияет на механизм challenge (407/401/redirect/form), метод сохранения состояния аутентификации (IP surrogate, cookie surrogate) и взаимодействие с клиентом.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
mode |
Ключевое слово | Режим аутентификации (см. таблицу ниже). |
Допустимые значения:
| Режим | Описание |
|---|---|
proxy |
Стандартный режим explicit proxy. Прокси возвращает 407 Proxy-Authenticate. Клиент отправляет учётные данные в заголовке Proxy-Authorization. Работает только с explicit proxy (не transparent). |
origin |
Прокси возвращает 401 WWW-Authenticate. Клиент отправляет учётные данные в заголовке Authorization. Подходит для reverse proxy и transparent proxy. |
origin-cookie |
401 challenge + cookie surrogate. После успешной аутентификации прокси устанавливает cookie, который используется для последующих запросов вместо повторного challenge. |
origin-cookie-redirect |
Redirect на виртуальный URL прокси для аутентификации, затем redirect обратно. Cookie surrogate сохраняет состояние. Рекомендуется для transparent proxy с HTTPS. |
origin-ip |
401 challenge + IP surrogate. После аутентификации IP-адрес клиента запоминается на указанный TTL. Подходит для сетей с фиксированными IP. |
origin-ip-redirect |
Redirect + IP surrogate. Аналогично origin-cookie-redirect, но состояние хранится по IP-адресу. |
form-cookie |
Вместо стандартного challenge отображается HTML-форма (captive portal). Cookie surrogate. Рекомендуется для пользовательских сетей. |
form-cookie-redirect |
Redirect на HTML-форму + cookie surrogate. Форма размещается на виртуальном URL прокси. |
form-ip |
HTML-форма + IP surrogate. |
form-ip-redirect |
Redirect на HTML-форму + IP surrogate. |
Тип: Нетерминальное. Устанавливает режим для последующих операций authenticate(). Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
<Proxy>
; Transparent proxy: использовать captive portal с cookie
authenticate.mode(form-cookie-redirect)
authenticate(Corporate_Realm)
См. также: authenticate(), authenticate.realm(), authenticate.force()
27.5. authenticate.realm()¶
Свойство authenticate.realm() устанавливает realm (область аутентификации) для последующей оценки CPL-правил. Влияет на выбор backend-валидатора, не вызывая запроса аутентификации.
В отличие от authenticate(realm), это свойство не генерирует challenge (407/401). Оно лишь определяет контекст для условий, связанных с аутентификацией (например, group=, user=, realm=), и для последующего authenticate() без аргументов или с другим realm.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
realm_name |
Строка | Имя realm для установки в контексте транзакции. |
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
<Proxy>
; Установить realm для проверки групп, но не требовать аутентификацию
authenticate.realm(LDAP_Realm)
check_authorization
group=Restricted_Users deny
allow
См. также: authenticate(), authenticate.force(), check_authorization
27.6. check_authorization¶
Свойство reverse proxy. Применимо только в сценарии, когда прокси стоит перед origin-сервером (OCS) и кеширует его ответы. Для forward proxy не актуально.
Свойство check_authorization используется в связке с CAD (Caching Authenticated Data) и CPAD (Caching Proxy-Authenticated Data). Применяется когда upstream-сервер (OCS) иногда (не всегда и не никогда) требует аутентификацию и авторизацию пользователя для доступа к объекту.
Установка значения yes приводит к:
1. Отправке GIMS (Get If Modified Since) запроса к OCS для проверки авторизации при каждом обращении к кешированному объекту.
2. Добавлению заголовка Cache-Control: must-revalidate в ответ клиенту.
Это гарантирует, что даже если объект закеширован, OCS проверит авторизацию пользователя перед отдачей — OCS ответит 304 (авторизован, отдать из кеша) или 403 (не авторизован).
Синтаксис:
Значение по умолчанию: no.
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Cache>, <Proxy>. HTTP и RTSP proxy-транзакции.
Пример (reverse proxy с OCS):
<Cache>
; Для защищённого раздела — всегда проверять авторизацию у OCS
url.path.prefix=/secure/ check_authorization(yes)
Примечание Redcoat: В нашей forward proxy реализации
check_authorizationпринимается, но фактически ничего не делает, т.к. у нас нет сценария кеширования контента с OCS-авторизацией. Группы пользователя загружаются автоматически приauthenticate()— отдельный шагcheck_authorizationне требуется.
См. также: cache(), always_verify(), bypass_cache(), authenticate()
27.7. authorize.add_group()¶
Свойство authorize.add_group() динамически добавляет успешно аутентифицированного пользователя в указанную группу на время текущей транзакции. Добавленная группа учитывается последующими проверками условия group= в CPL-правилах.
Только для аутентифицированных пользователей
Согласно BlueCoat, authorize.add_group() применяется только если пользователь успешно аутентифицирован. Для неаутентифицированного запроса свойство игнорируется. Поэтому правилу с add_group обычно предшествует authenticate(realm).
Добавление группы действует только в рамках текущей транзакции и не изменяет членство пользователя в backend-системе (LDAP, локальные группы). Используется для динамического назначения прав на основе условий CPL (адрес клиента, время, результат авторизации).
«Late condition guards early action»
Членство в группах известно только после аутентификации. Поэтому нельзя использовать group= как условие для authenticate() (например, group=xyz authenticate(realm) — ошибка компиляции). Условия, доступные с начала транзакции (client.address=, proxy.port=), использовать можно.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
group_name |
Строка | Имя группы для добавления. |
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Admin>, <Proxy>. Применяется ко всем proxy-транзакциям.
Пример 1. Назначение группы на основе IP-адреса:
<Proxy>
authenticate(Corporate_Realm)
client.address=10.10.0.0/16 authorize.add_group(VPN_Users)
group=VPN_Users allow
deny
Пример 2. Назначение группы по времени:
<Proxy>
authenticate(Corporate_Realm)
time=18:00..08:00 authorize.add_group(After_Hours)
group=After_Hours category=Social_Media allow
Пример 3. Группа по умолчанию при ошибке авторизации (канонический кейс BlueCoat): если аутентификация прошла, но проверка членства упала из-за недоступности сервера авторизации, назначить fallback-группу:
<Proxy>
authenticate(Corporate_Realm) authorize.tolerate_error(communication_error)
user.authorization_error=(communication_error) authorize.add_group(default_group)
См. также: check_authorization, authenticate(), authorize.tolerate_error(), Глава 12 (условия аутентификации)
27.8. authenticate.tolerate_error()¶
Свойство authenticate.tolerate_error() позволяет пропустить запрос без блокировки, если backend аутентификации вернул ошибку из списка допустимых. По умолчанию ошибки аутентификации приводят к отказу (deny). Это свойство позволяет определить, какие ошибки допустимо игнорировать.
Используется для обеспечения отказоустойчивости: если LDAP/RADIUS-сервер временно недоступен, пользователи продолжают получать доступ, а не блокируются.
Синтаксис:
Поддерживаются четыре синтаксических формы:
authenticate.tolerate_error(<error1>, <error2>, ...)
authenticate.tolerate_error[<error1>, <error2>](<yes|no>)
authenticate.tolerate_error(<yes|no>)
authenticate.tolerate_error.<error_name>(<yes|no>)
where:
| Параметр | Тип | Описание |
|---|---|---|
error |
Строка | Имя ошибки: ldap_server_down, ldap_timeout, radius_timeout, all и др. |
yes/no |
Булево | Включить/выключить толерантность для указанных ошибок. |
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример 1. Толерантность к ошибкам LDAP:
Пример 2. Включение/выключение по конкретной ошибке:
<Proxy>
authenticate(RADIUS_Realm)
authenticate.tolerate_error.radius_timeout(yes)
authenticate.tolerate_error.radius_server_down(no)
allow
См. также: authenticate(), authorize.tolerate_error()
27.9. authenticate.scheme()¶
Важно. Свойство принимается, но пока не применяется: схема challenge сейчас определяется конфигурацией realm, а не этим свойством.
Свойство authenticate.scheme() определяет схему аутентификации для текущей транзакции. Влияет на тип challenge (заголовок Proxy-Authenticate / WWW-Authenticate) и формат ожидаемых учётных данных.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
scheme |
Ключевое слово | Схема аутентификации: basic, ntlm, kerberos, negotiate, digest, form, certificate, saml, oauth. |
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
См. также: authenticate(), authenticate.realm(), authenticate.mode()
27.10. authenticate.2fa()¶
Важно. Свойство принимается, но пока не применяется — дополнительный фактор по этому свойству не запрашивается.
Свойство authenticate.2fa() требует двухфакторную аутентификацию для указанного realm. Применяется после первичной аутентификации и запрашивает дополнительный фактор (TOTP, SMS и т.д.).
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
realm_name |
Строка | Имя realm для двухфакторной аутентификации. |
Тип: Терминальное (условно). Если второй фактор не предоставлен — возвращает challenge.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
См. также: authenticate.2fa.method(), authenticate()
27.11. authenticate.2fa.method()¶
Важно. Свойство принимается, но пока не применяется (см. 27.10).
Свойство authenticate.2fa.method() определяет метод двухфакторной аутентификации.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
method |
Ключевое слово | Метод 2FA: totp, sms, email, push, fortitoken, hardware_token, certificate. |
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
<Proxy>
authenticate(Corporate_Realm)
authenticate.2fa(Corporate_Realm)
authenticate.2fa.method(totp)
allow
См. также: authenticate.2fa(), authenticate()
27.12. authorize.tolerate_error()¶
Важно. Свойство принимается, но пока не применяется — отдельной фазы авторизации в движке пока нет (см. также 12.7
user.authorization_error=).
Свойство authorize.tolerate_error() аналогично authenticate.tolerate_error(), но применяется к ошибкам авторизации (проверки членства в группах). Поддерживает те же четыре синтаксических формы.
Синтаксис:
authorize.tolerate_error(<error1>, <error2>, ...)
authorize.tolerate_error[<error1>, <error2>](<yes|no>)
authorize.tolerate_error(<yes|no>)
authorize.tolerate_error.<error_name>(<yes|no>)
Тип: Нетерминальное. Обработка слоёв продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.
Пример:
<Proxy>
authenticate(LDAP_Realm)
check_authorization
authorize.tolerate_error(ldap_server_down)
group=Admins allow
deny
См. также: authenticate.tolerate_error(), check_authorization
27.13. authenticate.force_307_redirect()¶
Свойство authenticate.force_307_redirect() управляет тем, какой HTTP-код используется для редиректа аутентификации в redirect-режимах (form-*-redirect, origin-*-redirect, а также form-режимы, выполняющие редирект на страницу входа /__proxy_login).
По умолчанию редирект на виртуальный URL аутентификации выполняется кодом 302 (Found). При authenticate.force_307_redirect(yes) используется 307 (Temporary Redirect). Ключевое отличие: 307 сохраняет метод и тело исходного запроса при редиректе, тогда как 302 многими клиентами преобразуется в GET. Это важно, когда незаафентифицированный запрос был, например, POST — после прохождения формы входа исходный POST должен быть воспроизведён без потери тела.
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
yes |
— | Редирект аутентификации выполняется кодом 307 (метод/тело сохраняются). |
no |
— | Редирект аутентификации выполняется кодом 302 (значение по умолчанию). |
Тип: Нетерминальное. Само по себе не вызывает challenge — лишь модифицирует код последующего редиректа аутентификации. Должно сопровождаться действием, генерирующим редирект (authenticate(realm) в form/redirect-режиме).
Слои и транзакции: <Proxy>. Применяется к HTTP proxy-транзакциям.
Пример:
<Proxy>
; ВСЕ auth-действия — на ОДНОМ правиле. В слое выигрывает первое совпадение (см. §43.2):
; разнесение по нескольким безусловным правилам применило бы только первое.
; authenticate(realm) запускает требование аутентификации→редирект; .mode(form) выбирает
; форму-редирект; .force_307_redirect(yes) делает этот редирект 307.
authenticate(Local) authenticate.mode(form) authenticate.force_307_redirect(yes)
authenticated=yes allow
deny
Результат: незаафентифицированный запрос получает ответ 307 Temporary Redirect с Location: /__proxy_login?url=...&realm=Local (вместо 302 Found). Браузер, переходя по редиректу, сохраняет исходный метод запроса.
⚠️ Важно (приоритет/потеря модификатора). Требование аутентификации — терминальное действие, но движок переносит вместе с ним накопленные нетерминальные auth-модификаторы (
force_307_redirect,mode, …), заданные на том же правиле. Поэтомуforce_307_redirectобязан стоять на том же правиле, что иauthenticate(realm)— иначе, поскольку выигрывает первое совпадение, он не дойдёт до фазы challenge, и редирект останется 302.Примечание. Имя и семантика стандартные (
authenticate.force_307_redirect(yes|no), значение по умолчаниюno, слой<Proxy>). Типичный пример — включение 307 для конкретного браузера черезrequest.header.User-Agent=.
См. также: authenticate(), authenticate.mode()
27.14. authenticate.forward_credentials()¶
Свойство authenticate.forward_credentials() управляет тем, передаются ли заголовки Authorization и Proxy-Authorization на вышестоящий origin-сервер (OCS) для данной транзакции.
authenticate.forward_credentials(yes)— передавать оба заголовка (AuthorizationИProxy-Authorization) на upstream.authenticate.forward_credentials(no)— не передавать: срезать оба заголовка перед отправкой запроса на OCS.
Применяется per-transaction: позволяет точечно разрешить/запретить проброс креденшелов для конкретных доменов (например, в multi-tenant сценариях или при проксировании к доверенному backend).
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
yes |
— | Передавать Authorization и Proxy-Authorization на upstream OCS. |
no |
— | Срезать оба заголовка перед upstream. |
Тип: Нетерминальное. Обработка слоя/правила продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP proxy-транзакциям.
Пример:
<Proxy>
; Пробрасывать креденшелы только на доверенный backend
url.domain=//myhost.com/ authenticate.forward_credentials(yes) allow
; Для остального трафика — не пробрасывать
authenticate.forward_credentials(no) allow
Результат: при (yes) заголовок Proxy-Authorization (обычно срезается как hop-by-hop) доходит до origin, как и Authorization. При (no) оба срезаются, и origin их не видит.
Особенность (значение по умолчанию). В Redcoat нет глобальной команды для управления пробросом учётных данных, поэтому при ОТСУТСТВИИ свойства действует штатное поведение прокси:
Authorization(сквозной заголовок) передаётся на origin, аProxy-Authorization(заголовок между соседними узлами) срезается. Свойствоforward_credentials()переопределяет это поведение для отдельной транзакции:(yes)дополнительно пробрасываетProxy-Authorization;(no)дополнительно срезаетAuthorization.Соответствие BlueCoat. Семантика свойства совпадает с BlueCoat: проброс заголовков
AuthorizationиProxy-Authorizationна сервер origin. Отличается только источник значения по умолчанию (см. примечание выше).
См. также: authenticate.forward_credentials.log()
27.15. authenticate.forward_credentials.log()¶
Свойство authenticate.forward_credentials.log() управляет тем, записывается ли в журнал событий (event log) факт проброса заголовков Authorization/Proxy-Authorization на upstream OCS. Используется совместно с authenticate.forward_credentials().
При (yes) каждый случай проброса креденшелов логируется (запись появляется только когда проброс действительно происходит, т.е. при forward_credentials(yes)).
Синтаксис:
Тип: Нетерминальное. Обработка слоя/правила продолжается.
Слои и транзакции: <Proxy>. Применяется к HTTP proxy-транзакциям.
Пример:
<Proxy>
; Пробросить креденшелы на myhost.com и залогировать действие
url.domain=//myhost.com/ authenticate.forward_credentials(yes) authenticate.forward_credentials.log(yes) allow
Результат: при пробросе креденшелов в журнал событий пишется запись о том, что Authorization/Proxy-Authorization отправлены на upstream.
Примечание. В Redcoat журналирование проброса учётных данных по умолчанию выключено.
См. также: authenticate.forward_credentials()
27.16. authenticate.persist_cookies()¶
Свойство authenticate.persist_cookies() управляет персистентностью cookie при cookie-surrogate аутентификации (режимы form-cookie, origin-cookie и их -redirect варианты).
authenticate.persist_cookies(no)— использовать session-cookie: заголовокSet-Cookieвыдаётся безMax-Age/Expires, браузер удаляет cookie при закрытии.authenticate.persist_cookies(yes)— использовать persistent-cookie:Set-CookieнесётMax-Age(cookie переживает перезапуск браузера).authenticate.persist_cookies(auto)— значение из настройки realm (в Redcoat по умолчанию = persistent).
Синтаксис:
where:
| Параметр | Тип | Описание |
|---|---|---|
auto |
— | Использовать значение, заданное в realm (дефолт). |
no |
— | Session-cookie (без Max-Age). |
yes |
— | Persistent-cookie (с Max-Age). |
Тип: Нетерминальное. Обработка слоя/правила продолжается. Влияет на Set-Cookie, выдаваемый при выпуске surrogate-cookie на успешной аутентификации.
Слои и транзакции: <Proxy>. Применяется к cookie-surrogate auth-режимам.
Пример:
<Proxy>
; На страницах mycompany использовать persistent-cookie, чтобы пользователь
; не логинился заново после перезапуска браузера.
url.host.regex=mycompany authenticate.persist_cookies(yes)
Результат: при (yes) surrogate-cookie __proxy_auth выдаётся с Max-Age (persistent); при (no) — без Max-Age (session, исчезает при закрытии браузера); при (auto) — как настроено в realm.
Реализация в Redcoat: значение влияет на
Set-Cookie, формируемый при выпуске cookie-surrogate.no→ опускаютсяMax-Age/Expires;yes/auto→ выставляетсяMax-Ageиз TTL surrogate.Соответствие BlueCoat. Совпадает с BlueCoat: управляет сохранением cookie при аутентификации. Значения:
auto— по умолчанию realm;no— сессионная cookie;yes— постоянная cookie. Слой<Proxy>.
См. также: authenticate.mode() (cookie-surrogate режимы)