Глава 8. Условия URL¶
Условия URL проверяют, соответствует ли часть запрошенного URL указанным критериям. Базовый тест url= пытается сопоставить полный URL запроса с указанным паттерном. Паттерн может включать scheme, host, port, path и query-компоненты URL. Если какой-либо из этих компонентов не включён в паттерн, соответствующий компонент URL запроса не проверяется и может иметь любое значение.
Специфические части URL можно проверять с помощью модификаторов компонентов: .domain, .host, .path, .port, .scheme, .extension, .address, .query. Для ряда компонентов также доступны модификаторы типа сопоставления: .regex, .suffix, .prefix, .substring.
Важно: условия
url=не допускаются в слое<Forward>. Для проверки URL в слое<Forward>используйте условияserver_url=(см. главу 23).
8.1. url=¶
Проверяет, соответствует ли полный URL запроса указанному паттерну. По умолчанию выполняется prefix match: паттерн url=http://example.com/docs совпадёт с http://example.com/docs, http://example.com/docs/page1.html и любым URL, начинающимся с этого префикса.
Паттерн может включать любую комбинацию компонентов URL: схему, хост, порт, путь и query string. Если компонент не указан в паттерне, он не проверяется. Например, паттерн url=example.com/docs проверяет хост и путь, но допускает любую схему (http, https и т.д.) и любой порт.
Если значение является именем, определённым в блоке define url condition или define url, оно раскрывается в список URL-паттернов.
Синтаксис:
where:
pattern— строка URL или её префикс. Может содержать scheme, host, port, path и query. Компоненты, не указанные в паттерне, не проверяются.define_name— имя блокаdefine url conditionилиdefine url, содержащего список URL-паттернов.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка доступа к конкретному URL
url=http://www.example.com/docs max_bitrate(no)
; Проверка URL с любой схемой
url=example.com/restricted deny
; Использование списка URL
url=blocked_urls deny
См. также: url.domain=, url.path=, url.regex=, server_url=.
8.1a. server_url= — URL-условие для слоя <Forward>¶
Проверяет URL запроса так же, как url=, но предназначено для слоя <Forward>, где условие url= не допускается. В <Forward> маршрутизация выполняется на основе server URL (URL, по которому прокси обращается к origin-серверу — после rewrite/forwarding), поэтому для тестов URL в этом слое используется семейство server_url.*.
Поддерживаются те же компонентные формы, что и для url=: проверка полного URL, хоста, домена, IP-адреса и регулярного выражения.
Имя как в BlueCoat. В
<Forward>url=запрещено — используйтеserver_url=(см. также раздел 4.6).
Синтаксис:
server_url=pattern
server_url.host=host
server_url.domain=domain
server_url.address={ip_address|subnet|subnet_label}
server_url.regex="pattern"
where:
pattern— строка URL или её префикс (аналогичноurl=);host— хост server URL (точное или wildcard-совпадение);domain— доменное имя или суффикс домена (аналогичноurl.domain=);ip_address— IP-адрес origin-сервера (см. такжеserver_url.address=в разделе 7.7);server_url.regex— регулярное выражение по полному server URL.
Слои и транзакции: <Forward> (основной); прочие компонентные формы доступны там же, где url.*.
Пример:
<Forward>
; Корпоративные домены — через внутренний upstream-прокси
server_url.domain=company.com forward(corp-proxy:8080)
; Конкретный хост — напрямую
server_url.host=updates.example.com direct
См. также: url= (8.1), server_url.address= (7.7), server_url.host.is_private= (8.7a), слой <Forward> (4.6).
8.2. url.domain=¶
Проверяет доменную часть запрошенного URL с учётом границ компонентов домена. Указание example.com автоматически включает как точное совпадение example.com, так и все поддомены: www.example.com, api.example.com, cdn.eu.example.com и т.д. При этом myexample.com НЕ совпадёт, поскольку domain учитывает границы компонентов (разделитель — точка).
Это ключевое отличие от url.host.suffix=, который выполняет простое строковое сравнение суффикса без учёта границ. Например, url.host.suffix=example.com совпадёт и с myexample.com, а url.domain=example.com — нет.
Если значение начинается с точки (.com, .ru), совпадают все домены в этой доменной зоне. Значение может быть именем блока define url.domain, содержащего список доменов.
Синтаксис:
url.domain[!]=domain_suffix_pattern
url.domain[!]=(domain_suffix_pattern, ...)
url.domain[!]=define_name
where:
domain_suffix_pattern— доменное имя или суффикс домена.example.comсовпадает сexample.comи*.example.com..comсовпадает со всеми доменами в зоне.com.define_name— имя блокаdefine url.domain, содержащего список доменов.!=или=!— отрицание: совпадает, если домен НЕ соответствует паттерну.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
define url.domain social_networks
facebook.com
twitter.com
instagram.com
end
<Proxy>
; Блокировка социальных сетей по define-списку
url.domain=social_networks deny
; Блокировка конкретного домена
url.domain=malware-site.org deny
; Блокировка всех доменов в зоне .xxx
url.domain=.xxx deny
; Все домены КРОМЕ корпоративного
url.domain!=company.com deny
См. также: url.host=, url.host.suffix=, define url.domain.
8.3. url.host=¶
Проверяет host-часть запрошенного URL. По умолчанию выполняется точное совпадение (exact match): url.host=www.example.com совпадёт только с www.example.com, но не с example.com или api.example.com.
В отличие от url.domain=, условие url.host= не раскрывает поддомены автоматически. Для проверки хоста с поддоменами используйте url.domain=.
Поддерживает отрицание через != или =!.
Примечание: В BlueCoat CPL также поддерживается модификатор
url.host.exact=для явного указания точного совпадения. В Redcoaturl.host=уже выполняет точное совпадение по умолчанию, поэтому отдельный модификатор.exactне реализован.
Синтаксис:
where:
host— точное имя хоста (FQDN). Сравнение выполняется без учёта регистра.!=или=!— отрицание.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Разрешить только конкретный хост
url.host=updates.company.com ALLOW
; Заблокировать конкретный сервер
url.host=bad-server.example.com deny
; Отрицание: всё кроме указанного хоста
url.host!=intranet.company.com deny
См. также: url.domain=, url.host.suffix=, url.host.prefix=, url.host.regex=.
8.4. url.host.suffix= / url.host.prefix=¶
Проверяет, оканчивается ли (suffix) или начинается ли (prefix) имя хоста на указанную строку. Это строковое сравнение без учёта границ компонентов домена. Поэтому url.host.suffix=example.com совпадёт как с www.example.com, так и с myexample.com — в отличие от url.domain=example.com, который учитывает границу точки.
Модификатор .prefix проверяет начало имени хоста. Например, url.host.prefix=api совпадёт с api.example.com, api-v2.corp.net и apiserver.local.
Важно:
.prefixи.suffix— это строковые сравнения. Они не учитывают границы компонентов домена. Для проверки с учётом границ используйтеurl.domain=.
Синтаксис:
url.host.suffix=string
url.host.suffix=(string, string, ...)
url.host.prefix=string
url.host.prefix=(string, string, ...)
where:
string— строковый суффикс или префикс для проверки имени хоста. Сравнение без учёта регистра.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка хостов, оканчивающихся на .cryptopro.ru
url.host.suffix=.cryptopro.ru deny
; Блокировка хостов, начинающихся на bad-
url.host.prefix=bad- deny
; Список суффиксов
url.host.suffix=(.cn, .ru, .ir) deny
См. также: url.domain=, url.host=, url.host.substring=.
8.5. url.host.substring=¶
Проверяет, содержит ли имя хоста указанную подстроку в любой позиции. Это строковое сравнение без учёта границ компонентов: url.host.substring=example совпадёт с example.com, my-example.org, testexample.net и любым хостом, содержащим последовательность символов example.
Используйте url.host.substring= для «нечёткого» поиска по имени хоста, когда точная позиция совпадения не важна.
Синтаксис:
where:
string— подстрока для поиска внутри имени хоста. Сравнение без учёта регистра.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка хостов, содержащих "porn" в имени
url.host.substring=porn deny
; Блокировка хостов с "malware" в имени
url.host.substring=malware deny
См. также: url.host=, url.host.suffix=, url.host.prefix=, url.host.regex=.
8.6. url.host.regex=¶
Проверяет имя хоста регулярным выражением (Perl-совместимый синтаксис). Регулярное выражение применяется только к host-части URL (без scheme, порта, пути и query).
Регулярные выражения дают максимальную гибкость при проверке имени хоста, но работают медленнее, чем другие модификаторы (url.domain=, url.host=, url.host.suffix=). Используйте regex только когда другие модификаторы не позволяют выразить нужное условие.
Синтаксис:
where:
regular_expression— Perl-совместимое регулярное выражение. Рекомендуется заключать в кавычки, если содержит пробелы или спецсимволы CPL.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Хосты вида www1.example.com, www2.example.com, ...
url.host.regex="^www\d+\.example\.com$" ALLOW
; Хосты, начинающиеся на api или cdn
url.host.regex="^(api|cdn)\..+" deny
; Хосты с двойным расширением (подозрительные)
url.host.regex="\.\w+\.\w+\.\w+$" deny
См. также: url.host=, url.host.substring=, url.regex=.
8.7. url.host.is_private=¶
Проверяет, находится ли хост запрошенного URL в приватной сети. Приватными считаются адреса из RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), а также loopback (127.0.0.0/8) и link-local (169.254.0.0/16) диапазоны.
Если хост URL указан как доменное имя, выполняется DNS-resolve и проверяется полученный IP-адрес. Если хост URL указан как IP-адрес (numeric URL), проверяется непосредственно этот адрес.
Это условие полезно для разделения внутреннего и внешнего трафика, например, при маршрутизации через upstream-прокси: внутренний трафик отправляется напрямую, а внешний — через вышестоящий прокси.
Синтаксис:
where:
yes— совпадает, если IP-адрес хоста принадлежит приватному диапазону.no— совпадает, если IP-адрес хоста НЕ принадлежит приватному диапазону (публичный адрес).
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Forward>
; Внутренние ресурсы — напрямую, остальное — через upstream
url.host.is_private=yes direct
forward(upstream-proxy.corp:3128)
<Proxy>
; Логирование обращений к внутренним хостам
url.host.is_private=yes access_log(internal)
См. также: url.address=, client.address=.
8.7a. server_url.host.is_private=¶
Проверяет, находится ли хост server URL в приватной сети. Семантически идентично url.host.is_private= (8.7): приватными считаются адреса из RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), а также loopback (127.0.0.0/8) и link-local (169.254.0.0/16) диапазоны. Если хост указан доменным именем, выполняется DNS-resolve и проверяется полученный IP-адрес; если хост указан как IP-адрес, проверяется он непосредственно.
Условие предназначено для слоя <Forward>, где url=/url.host.* не допускаются — для тестов URL в этом слое используется семейство server_url.*. Типичный сценарий: внутренний трафик отправлять напрямую, а внешний — через вышестоящий прокси.
Имя как в BlueCoat.
Синтаксис:
where:
yes— совпадает, если IP-адрес хоста принадлежит приватному диапазону.no— совпадает, если IP-адрес хоста НЕ принадлежит приватному диапазону (публичный адрес).
Слои и транзакции: <Forward>.
Пример:
<Forward>
; Внутренние ресурсы — напрямую, остальное — через upstream
server_url.host.is_private=yes direct
forward(upstream-proxy.corp:3128)
См. также: url.host.is_private= (8.7), server_url= (8.1a), server_url.address= (7.7).
8.8. url.path=¶
Проверяет path-часть запрошенного URL. Path определяется как всё от первого / после хоста до конца URL (включая query string).
По умолчанию выполняется prefix match: url.path=/api/ совпадёт с /api/, /api/v1/users, /api/data?key=value и любым путём, начинающимся с /api/. Паттерн url.path=/ совпадает с любым URL, поскольку все пути начинаются с /.
Поддерживает отрицание через != или =!, а также списки значений.
Примечание: Поскольку
url.path=уже выполняет prefix match по умолчанию, отдельный модификатор.prefixне требуется (но поддерживается парсером для совместимости).
Синтаксис:
where:
prefix_pattern— строковый префикс пути. Сравнение выполняется без учёта регистра.!=или=!— отрицание: совпадает, если путь НЕ начинается с указанного префикса.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка административных путей
url.path=/admin deny
; Блокировка нескольких путей
url.path=(/admin, /internal, /debug) deny
; Path с query string
url.path="/cgi-bin/query.pl?q=test" deny
; Всегда совпадает (любой путь начинается с /)
url.path="/" access_log(yes)
См. также: url.path.regex=, url.path.substring=, url.path.suffix=.
8.9. url.path.substring= / url.path.suffix=¶
Проверяет, содержит ли path-часть URL указанную подстроку (substring) или оканчивается ли на указанный суффикс (suffix). Оба модификатора выполняют строковое сравнение без учёта границ компонентов пути.
url.path.substring=admin совпадёт с /admin/panel, /my/admin/page и /administrator. url.path.suffix=.php совпадёт с /index.php, /api/data.php, но не с /index.php?id=1 (query string является частью path).
Примечание:
url.path=уже выполняет prefix match. Поэтому отдельный модификаторurl.path=избыточен, но поддерживается парсером для совместимости с BlueCoat.
Синтаксис:
where:
string— подстрока или суффикс для поиска внутри path-части URL.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка путей, содержащих "admin"
url.path.substring=admin deny
; Блокировка PHP-скриптов
url.path.suffix=.php deny
; Блокировка directory traversal
url.path.substring=.. deny
См. также: url.path=, url.path.regex=.
8.10. url.path.regex=¶
Проверяет path-часть URL регулярным выражением (Perl-совместимый синтаксис). Регулярное выражение применяется к полной path-части, включая query string.
Используйте regex, когда prefix/substring/suffix-модификаторы не позволяют выразить нужное условие — например, для проверки числовых идентификаторов в пути, сложных шаблонов или directory traversal атак.
Синтаксис:
where:
regular_expression— Perl-совместимое регулярное выражение. Рекомендуется заключать в кавычки.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; REST API с числовым ID
url.path.regex="^/api/v[0-9]+/users/\d+$" ALLOW
; PHP-скрипты с query string
url.path.regex="\.php\?" deny
; Directory traversal
url.path.regex="\.\.\/" deny
См. также: url.path=, url.path.substring=.
8.11. url.regex=¶
Проверяет полный URL (включая scheme, host, port, path и query string) регулярным выражением (Perl-совместимый синтаксис).
Это наиболее мощный, но и наиболее ресурсоёмкий способ проверки URL. Регулярное выражение применяется ко всей строке URL целиком. Где возможно, предпочитайте более специализированные условия (url.domain=, url.host.regex=, url.path.regex=), которые работают быстрее за счёт проверки только одного компонента.
Расширение Redcoat. В BlueCoat CPL синтаксис
url.regex=формально отсутствует как самостоятельное условие. BlueCoat использует конструкциюurl.string_modifier=pattern, гдеstring_modifierможет бытьregex. Redcoat поддерживаетurl.regex=как отдельное явное условие для удобства и единообразия сurl.host.regex=иurl.path.regex=.
Синтаксис:
where:
regular_expression— Perl-совместимое регулярное выражение, применяемое к полному URL. Рекомендуется заключать в кавычки.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка torrent-файлов на любом хосте
url.regex="https?://.*\.(torrent|magnet)$" deny
; Блокировка определённого API паттерна
url.regex="https?://.*\.example\.com/api/v[12]/admin" deny
См. также: url.host.regex=, url.path.regex=, url=.
8.11a. Условия raw_url.* — сырой (ненормализованный) URL¶
Семейство условий проверяет URL до нормализации (как он пришёл в запросе), регулярным выражением. Полезно против техник обхода, которые маскируют вредоносный URL за счёт кодирования/регистра, теряемых при нормализации.
raw_url.regex="pattern" ; весь сырой URL
raw_url.host.regex="pattern" ; сырой хост (нормализован к нижнему регистру)
raw_url.path.regex="pattern" ; сырой path (если отличается от нормализованного)
raw_url.query.regex="pattern" ; сырой query (без нормализации URL)
raw_url.pathquery.regex="pattern" ; сырой path+query
Слои и транзакции: <Proxy>.
Пример:
<Proxy>
; Поймать path-traversal в сыром виде (до нормализации)
raw_url.path.regex="\.\.(/|%2[fF])" deny
; Обход через query, теряемый при нормализации
raw_url.query.regex="(?i)(union|select).*from" deny
Имена
raw_url.*соответствуют BlueCoat (url.string_modifier-семейство сырого URL). У всех пяти — только форма.regex.
8.12. url.extension=¶
Проверяет расширение файла в URL. Расширение определяется как последовательность символов после последней точки в path-части URL (до query string). Точка в значении условия необязательна: url.extension=txt и url.extension=.txt эквивалентны.
Пустая строка url.extension="" совпадает с URL, не содержащими расширения файла (например, /api/users или /about).
Синтаксис:
where:
filename_extension— расширение файла, с точкой или без. Сравнение без учёта регистра.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка загрузки исполняемых файлов
url.extension=(exe, msi, bat, cmd, ps1, vbs, scr) deny
; Разрешить только определённые типы контента
url.extension=(htm, html, css, js, png, jpg, gif) ALLOW
; Разные расширения изображений
url.extension=(img, jpg, jpeg, png, gif, webp, svg) ALLOW
См. также: url.path=, url.path.regex=.
8.13. url.query=¶
Проверяет query string запрошенного URL.
В BlueCoat CPL для проверки query string доступен только модификатор url.query.regex= (регулярное выражение). Redcoat расширяет эту функциональность, поддерживая url.query= с точным и списковым сопоставлением, что удобнее для простых проверок. Модификатор url.query.regex= в текущей версии не реализован.
Расширение Redcoat. Условие
url.query=с точным/списковым сопоставлением отсутствует в BlueCoat CPL (там есть толькоurl.query.regex=). Redcoat поддерживаетurl.query=для удобства. Поддержкаurl.query.regex=планируется.
Синтаксис:
where:
string— значение query string или его часть для сопоставления.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Блокировка запросов с отладочным параметром
url.query=debug=true deny
; Блокировка запросов с API-ключом
url.query="api_key=secret" deny
См. также: url.path=, url.path.regex=.
8.14. url.scheme=¶
Проверяет scheme-часть (протокол) запрошенного URL. Поддерживаемые схемы: http, https, ftp, socks.
Условие полезно для разделения HTTP и HTTPS трафика, применения разных политик в зависимости от протокола, а также для блокировки нежелательных протоколов.
Поддерживает отрицание через != или =!.
Синтаксис:
where:
url_scheme— одно из значений:http,https,ftp,socks.!=или=!— отрицание.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Запретить незашифрованный HTTP
url.scheme=http deny
; Разрешить только HTTPS
url.scheme!=https deny
См. также: url.port=, url=.
8.15. url.port=¶
Проверяет номер порта в запрошенном URL. Если порт не указан явно в URL, используется порт по умолчанию для данной схемы: 80 для http, 443 для https, 21 для ftp, 1080 для socks.
Поддерживает одиночные значения, списки и диапазоны. Поддерживает отрицание через != или =!.
Синтаксис:
url.port[!]=port_number
url.port[!]=(port_number, port_number, ...)
url.port[!]=range_start..range_end
where:
port_number— номер порта (1-65535).range_start..range_end— диапазон портов (включительно).!=или=!— отрицание.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
<Proxy>
; Разрешить только стандартные порты
url.port=(80, 443) ALLOW
; Заблокировать нестандартные порты
url.port!=80 url.port!=443 deny
; Заблокировать диапазон портов
url.port=8000..9000 deny
См. также: url.scheme=, proxy.port=, server.port=.
8.16. url.address=¶
Проверяет IP-адрес, в который разрешилось доменное имя хоста URL через DNS. Перед оценкой этого условия выполняется DNS-resolve доменного имени. Если URL содержит IP-адрес вместо доменного имени (numeric URL), проверяется этот адрес непосредственно.
Поддерживает одиночные IP-адреса, CIDR-подсети и ссылки на define subnet. Поддерживает отрицание через != или =!.
Примечание: В BlueCoat CPL также поддерживаются
ip_address_range,ip_address_wildcardsиsubnet_label. В Redcoat поддерживаются одиночные IP-адреса, CIDR-подсети и ссылки наdefine subnet.
Синтаксис:
where:
ip_address— одиночный IPv4- или IPv6-адрес (например,10.1.198.0,::1).subnet— CIDR-подсеть (например,10.0.0.0/8,192.168.0.0/16).subnet_label— имя блокаdefine subnet.!=или=!— отрицание.
Слои и транзакции: Cache, Exception, Proxy, SSL, SSL-Intercept.
Пример:
define subnet internal_nets
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
end
<Proxy>
; Разрешить доступ к внутренним серверам
url.address=internal_nets ALLOW
; Заблокировать конкретный IP
url.address=10.1.198.0 deny
; Отрицание: всё кроме внутренних сетей
url.address!=192.168.0.0/16 deny
См. также: url.host.is_private=, client.address=, url.address=.
8.17. url.is_absolute=¶
Синтаксис и семантика — как в BlueCoat (тест семейства
url=).
Проверяет, является ли URL запроса абсолютным (содержит схему и хост), в отличие от относительного.
Синтаксис:
Допустимые слои: <Proxy>.
Примеры:
8.18. url.host.is_numeric=¶
Синтаксис и семантика — как в BlueCoat (тест семейства
url=).
Проверяет, задан ли хост URL числовым IP-адресом (литералом), а не доменным именем. Часто используется для блокировки обращений по «голому» IP в обход категоризации.
Синтаксис:
Допустимые слои: <Proxy>.
Примеры:
8.19. url.host.has_name= / url.host.no_name=¶
Имена как в BlueCoat (тест семейства
url=).
Проверяют, задан ли хост URL именем (а не IP-литералом).
Отличие от BlueCoat: в BlueCoat значение определяется реальным reverse-DNS (PTR) lookup и принимает расширенные коды (
restricted/refused/nxdomain/error). В Redcoat реализована эвристика «хост не является IP-литералом» и принимаются толькоyes|no.
Синтаксис:
url.host.has_name={yes|no}
url.host.no_name={yes|no}
server_url.host.has_name={yes|no} ; для upstream URL; также короткая форма server_url.has_name=
Значение has_name |
Описание |
|---|---|
yes |
хост задан именем |
no |
хост задан IP-литералом |
Допустимые слои: <Proxy>.
Примеры: