Перейти к содержанию

Глава 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) и ожидает повторный запрос с учётными данными.

Синтаксис:

authenticate(<realm_name>)

where:

Параметр Тип Описание
realm_name Строка Имя realm, настроенного в конфигурации прокси. Определяет backend аутентификации и его параметры.

Тип: Терминальное (условно). Если пользователь не аутентифицирован — обработка прекращается, клиенту возвращается 407/401. Если уже аутентифицирован — действие пропускается (нетерминальное поведение).

Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.

Пример 1. Обязательная аутентификация:

<Proxy>
    authenticate(LDAP_Realm)
    allow

Пример 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) явно отключает требование аутентификации для совпавшего запроса. Запрос пропускается без проверки учётных данных, даже если другие правила в том же слое требуют аутентификацию.

Синтаксис:

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 — это позволяет принудительно запросить учётные данные перед отклонением запроса. Используется для сценариев смены пароля, повышенной безопасности для критичных ресурсов и повторной проверки при подозрении на компрометацию сессии.

Синтаксис:

authenticate.force(<realm_name>)

where:

Параметр Тип Описание
realm_name Строка Имя realm для принудительной аутентификации.

Тип: Терминальное. Всегда возвращает challenge (407/401), независимо от текущего состояния аутентификации.

Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.

Пример 1. Принудительная аутентификация для критичных ресурсов:

<Proxy>
    url.path=/admin/(.*) authenticate.force(Corporate_Realm)

Пример 2. Повторная аутентификация при доступе к финансовым данным:

<Proxy>
    authenticate(Corporate_Realm)
    category=Financial authenticate.force(Corporate_Realm)
    allow

См. также: authenticate(), authenticate(no), authenticate.realm()


27.4. authenticate.mode()

Свойство authenticate.mode() определяет способ передачи и хранения учётных данных для данной транзакции. Режим влияет на механизм challenge (407/401/redirect/form), метод сохранения состояния аутентификации (IP surrogate, cookie surrogate) и взаимодействие с клиентом.

Синтаксис:

authenticate.mode(<mode>)

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.

Синтаксис:

authenticate.realm(<realm_name>)

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 (не авторизован).

Синтаксис:

check_authorization(yes|no)

Значение по умолчанию: 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=), использовать можно.

Синтаксис:

authorize.add_group(<group_name>)

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:

<Proxy>
    authenticate(LDAP_Realm)
    authenticate.tolerate_error(ldap_server_down, ldap_timeout)
    allow

Пример 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) и формат ожидаемых учётных данных.

Синтаксис:

authenticate.scheme(<scheme>)

where:

Параметр Тип Описание
scheme Ключевое слово Схема аутентификации: basic, ntlm, kerberos, negotiate, digest, form, certificate, saml, oauth.

Тип: Нетерминальное. Обработка слоёв продолжается.

Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.

Пример:

<Proxy>
    authenticate.scheme(negotiate)
    authenticate(Corporate_Realm)

См. также: authenticate(), authenticate.realm(), authenticate.mode()


27.10. authenticate.2fa()

Важно. Свойство принимается, но пока не применяется — дополнительный фактор по этому свойству не запрашивается.

Свойство authenticate.2fa() требует двухфакторную аутентификацию для указанного realm. Применяется после первичной аутентификации и запрашивает дополнительный фактор (TOTP, SMS и т.д.).

Синтаксис:

authenticate.2fa(<realm_name>)

where:

Параметр Тип Описание
realm_name Строка Имя realm для двухфакторной аутентификации.

Тип: Терминальное (условно). Если второй фактор не предоставлен — возвращает challenge.

Слои и транзакции: <Proxy>. Применяется к HTTP/HTTPS proxy-транзакциям.

Пример:

<Proxy>
    authenticate(Corporate_Realm)
    url.path=/admin/(.*) authenticate.2fa(Corporate_Realm)
    allow

См. также: authenticate.2fa.method(), authenticate()


27.11. authenticate.2fa.method()

Важно. Свойство принимается, но пока не применяется (см. 27.10).

Свойство authenticate.2fa.method() определяет метод двухфакторной аутентификации.

Синтаксис:

authenticate.2fa.method(<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 должен быть воспроизведён без потери тела.

Синтаксис:

authenticate.force_307_redirect(yes|no)

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).

Синтаксис:

authenticate.forward_credentials(yes|no)

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)).

Синтаксис:

authenticate.forward_credentials.log(yes|no)

Тип: Нетерминальное. Обработка слоя/правила продолжается.

Слои и транзакции: <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).

Синтаксис:

authenticate.persist_cookies(auto|no|yes)

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 режимы)