Blog

WAF для HCL Domino: парсинг Notes-форм и GeoIP-блокировка

Если вы администрируете веб-приложение на HCL Domino, вы наверняка сталкивались с ситуацией, когда стандартные средства защиты просто отказываются работать. Cloudflare, ModSecurity, AWS WAF и десятки других решений смотрят на HTTP-трафик через призму Apache, Nginx или IIS. Domino же использует собственный HTTP-стек, в котором запросы обрабатываются иначе: параметры форм передаются в @-формулы, агенты вызываются через URL, а пути вида /database.nsf/Form?OpenForm не укладываются в привычные сигнатуры. В итоге WAF видит « нормальный » запрос, пропускает его, а на сервере выполняется @Command([FileSave]) или запускается агент с правами владельца базы.

Именно поэтому российский аналог Cloudflare и любая другая облачная защита требуют глубокой адаптации под Domino. Универсальные правила здесь не работают: нужно парсить Notes-формы, извлекать @-формулы из параметров, проверять вызовы агентов и одновременно фильтровать трафик по GeoIP. Без этого L7 DDoS, защита от ботов и WAF-блокировки превращаются в формальность, а сайт остаётся уязвимым для инъекций, которые не видны на уровне стандартного reverse proxy. Замена Cloudflare в России в 2026 году это не только вопрос доступности, но и вопрос совместимости с ИТ-инфраструктурой, где Domino занимает критическое место.

TrafficVeil, DDoS-Guard, Qrator и Angie PRO по-разному подходят к этой задаче. Одни предлагают только сетевую фильтрацию, другие требуют кастомных модулей, третьи вообще не поддерживают разбор Notes-форм. В этой статье мы разберём, как устроен HTTP-стек Domino, какие уязвимости скрываются в @Commands и агентах, как настроить GeoIP-блокировку без потери производительности и почему без специализированного WAF-профиля защита Domino остаётся дырявой. Если вы ищете альтернативу Cloudflare для сайтов на Notes, здесь вы найдёте конкретные архитектурные решения и процедуры настройки.

Архитектура HTTP-стека HCL Domino и почему стандартные WAF не справляются

HCL Domino – это не просто веб-сервер, а целая платформа приложений с собственной моделью данных, где документы, представления и агенты живут в формате NSF, а не в таблицах MySQL. HTTP-стек здесь тоже свой: встроенный HTTP-сервер Domino (в документации он фигурирует как Domino HTTP Server / nHTTP) обрабатывает запросы напрямую, без Apache, Nginx или другого внешнего демона. Это принципиальный момент, который ломает всю логику работы привычных WAF и обратных прокси.

Когда Cloudflare или любой другой reverse proxy получает запрос к Domino-приложению, он видит обычный HTTP-трафик: GET, POST, куки, заголовки. Но дальше начинается магия Domino. Параметры формы могут содержать @-формулы, специальные поля с префиксом $$, ссылки на агентов через ?OpenAgent, обращения к $$OpenDominoDocument. Всё это обрабатывается внутри nHTTP и интерпретируется движком Domino. Внешний прокси не знает семантики этих конструкций, он видит просто строки. Cloudflare инспектирует на уровне L7 по своим сигнатурам, но сигнатур @Commands у него нет и быть не может – это проприетарный синтаксис IBM/HCL, который не встречается в типовых правилах ModSecurity или OWASP CRS.

Почему различия в парсинге запросов критичны для WAF

Domino парсит запросы не так, как Nginx или Apache. Во-первых, он поддерживает собственные URL-схемы: /database.nsf/FormName?OpenForm, /database.nsf/AgentName?OpenAgent, /database.nsf/ViewName?OpenView. Во-вторых, параметры формы могут передаваться в формате, где имя поля совпадает с именем Notes-поля, и значение затем подставляется в формулу. В-третьих, Domino умеет обрабатывать multipart-запросы с вложениями и rich-text полями, которые стандартные WAF часто режут или нормализуют неверно, ломая легитимные сценарии.

Практический пример: POST на /app.nsf/Order?OpenForm с полем Command=@MailSend. Обычный WAF видит строку « @MailSend » и по своим правилам может либо пропустить её (нет сигнатуры), либо заблокировать как подозрительную (если включены агрессивные фильтры XSS). Но настоящая угроза в том, что Domino выполнит эту формулу на сервере, если поле попадёт в вычисляемое поле формы или в агент. Внешний прокси не может отличить легитимное использование @-формулы от инъекции, потому что не знает контекста формы и прав доступа.

Ещё один факт: Domino HTTP Server не поддерживает mod_security и не умеет подключать внешние WAF-модули через стандартные хуки. Единственные точки расширения – DSAPI (Domino Server API) и HTTP-фильтры (Web Site Rules / Internet Site документы). Это значит, что облачная защита Cloudflare, которая работает на уровне DNS и обратного прокси, физически не может инспектировать трафик внутри Domino. Она либо пропускает всё, либо блокирует по внешним признакам, не понимая логику Notes-форм. Российские интернет-провайдеры, ограничивающие доступ к сайтам на Cloudflare, добавляют ещё один слой проблем: даже если вы настроили Cloudflare, часть аудитории в РФ просто не достучится до вашего Domino-сервера.

Итог: для защиты Domino нужен WAF, который умеет парсить Notes-формы, извлекать @-формулы, проверять параметры агентов и при этом работать либо как модуль внутри Domino (через DSAPI), либо как reverse proxy с кастомными правилами под NSF. Стандартные решения этого не делают, поэтому бизнес в России ищет альтернативу Cloudflare, которая понимает специфику Domino. TrafficVeil, например, объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS и GeoIP-фильтрацию, но для Domino критично именно умение разбирать Notes-формы и блокировать @Commands на уровне, где это имеет смысл.

Ключевые уязвимости Notes-форм: @Commands, агенты и формула-инъекции

Notes-формы это не HTML-формы в привычном смысле. Когда пользователь открывает документ через браузер, Domino генерирует разметку на лету, подставляя значения полей, вычисленные формулы и скрытые служебные поля. Именно здесь и живёт основная масса L7-уязвимостей: злоумышленник не ломает сервер, он заставляет Domino выполнить то, что задумано разработчиком, но в чужом контексте.

Самый распространённый вектор это инъекция @-формул через поля формы. Если поле ввода не экранируется перед сохранением или перед повторным вычислением, атакующий отправляет значение вида @MailSend или @DbLookup и заставляет сервер отработать команду при следующем открытии документа. Формально это валидная формула, поэтому сигнатурные WAF на уровне HTTP её не видят: запрос выглядит как обычный POST с текстовым значением поля.

Агенты, $$OpenDominoDocument и другие скрытые каналы

Второй пласт это вызов агентов через HTTP. Domino позволяет запускать агенты по URL вида /database.nsf/agent?OpenAgent, и если агент не проверяет контекст вызова, его можно дёрнуть напрямую из браузера, минуя форму. Агент выполнится с правами сервера, а не пользователя, что открывает доступ к базам, к которым обращавшегося не должно пускать. Стандартные WAF редко блокируют такие запросы, потому что путь выглядит легитимным.

Отдельная история это манипуляции с $$OpenDominoDocument и родственными служебными полями. Через них можно подменить идентификатор документа, изменить режим открытия, заставить сервер отдать содержимое другого документа или выполнить действие от имени другого пользователя. Всё это происходит внутри одного HTTP-запроса, без аномалий в заголовках и без характерных для веб-атак паттернов вроде UNION SELECT или <script>. Классический WAF, настроенный на SQLi и XSS, просто пропускает трафик дальше.

Дополнительные векторы, которые стоит держать в голове:

  • Подмена параметров OpenView и OpenForm для доступа к представлениям, скрытым от пользователя.
  • Инъекции в Query_String и Path_Info, которые Domino разбирает по своим правилам, отличным от Apache и Nginx.
  • Эксплуатация полей с вычисляемыми формулами, где значение подставляется в @Command([FileSave]) или @Command([Compose]).
  • Обход аутентификации через манипуляции с DomAuthSessId и повторным использованием сессионных cookie.

Почему это не ловят обычные WAF: HCL Domino использует собственный HTTP-сервер, а не Apache или Nginx. Обратный прокси видит только сырой поток байт, но не понимает семантику Notes-форм, не различает служебные поля и не знает, какие @-формулы опасны в конкретной базе. Чтобы блокировать такие атаки, нужен WAF, который парсит Notes-формы как Notes-формы, извлекает @-формулы и проверяет параметры агентов до того, как запрос дойдёт до Domino. Об этом и пойдёт речь дальше.

Принципы работы WAF-профиля для Domino: парсинг Notes-форм и сигнатуры @Commands

Стандартный WAF смотрит на HTTP-запрос как на текст: метод, путь, заголовки, тело. Для Domino этого мало. Notes-форма приходит не как аккуратный JSON, а как набор полей вида %%Surrogate_FieldName, __Click, $$OpenDominoDocument, где значения могут содержать многострочные конструкции с @-формулами, ссылками на представления и вызовами агентов. Специализированный WAF-профиль для Domino должен уметь разбирать эту структуру до того, как запрос дойдёт до HTTP-задачи сервера. Иначе защита превращается в фильтр по регуляркам, который либо пропускает обфусцированные полезные нагрузки, либо режет легитимный трафик.

Первый слой профиля – нормализация Notes-форм. WAF извлекает из POST-тела все пары имя-значение, декодирует URL-encoding и HTML-entities, склеивает фрагментированные поля, которые Domino собирает по частям. Отдельно обрабатываются поля с префиксом $$ и служебные __, потому что именно через них чаще всего пытаются влиять на логику документа. На выходе получается дерево полей с исходными смещениями, чтобы при блокировке можно было точно указать, какой параметр сработал.

Второй слой – извлечение @-формул. Любое значение поля проверяется на наличие символа @ в начале токена или после разделителя. Кандидаты складываются в отдельный буфер и прогоняются через парсер, который распознаёт известные команды: @Command, @DbLookup, @MailSend, @SetField, @Environment, @Do. Важно не просто искать строку « @Command », а разбирать вложенность скобок и кавычек, потому что атакующий может написать @Com"+"mand или использовать Unicode-гомоглифы. Парсер приводит значение к канонической форме и только потом сравнивает с сигнатурами.

Третий слой – проверка параметров агентов. Запуск агента через HTTP идёт по пути вида /database.nsf/agentname?OpenAgent с параметрами, которые агент читает через DocumentContext или Query_String. WAF-профиль знает список разрешённых агентов для каждой базы, ограничивает допустимые имена параметров и типы значений, блокирует попытки передать в параметр @-формулу или путь к другой базе. Если агент не помечен как публичный, запрос к нему отклоняется на уровне фильтра ещё до инициализации Notes-сессии.

Четвёртый слой – сигнатуры и решение. Сигнатуры делятся на три группы: жёсткие (явное @Command с опасными аргументами, попытки записи в $$ScriptName, инъекция в $$OpenDominoDocument), эвристические (аномальная длина значения, несоответствие заявленного Content-Type реальному телу, признаки обфускации) и репутационные (IP из списка, частота обращений к агентам). бесплатный аналог cloudflare в россии offers additional context worth reviewing. Жёсткие срабатывания блокируют запрос сразу, эвристические отправляют его в карантин с логированием полного дерева полей, репутационные влияют на приоритет обработки. Все решения принимаются до вызова Domino HTTP-задачи, поэтому сервер не тратит ресурсы на разбор заведомо враждебного запроса.

Логирование строится вокруг Notes-сущностей, а не вокруг URL. В журнале фиксируются база, форма, имя агента, извлечённые @-формулы и сработавшая сигнатура. Это даёт администратору понятную картину: не « заблокирован POST /database.nsf », а « заблокирована @-формула @Command([FileSave]) в поле Body формы MainTopic от IP 203.0.113.44 ». Такой формат упрощает и разбор инцидентов, и тонкую настройку правил под конкретную конфигурацию Domino-приложения.

GeoIP-блокировка на уровне Domino: настройка и обходные пути

GeoIP-фильтрация в HCL Domino реализуется тремя путями, и выбор между ними определяет, насколько быстро вы сможете закрыть трафик из нежелательных стран. Первый путь – встроенные правила в Internet Site документе (серверный документ в Domino Directory). Там есть поле « TCP/IP Access Restrictions » с масками подсетей, но не с кодами стран. Domino не умеет резолвить IP в страну на уровне ядра HTTP-сервера. Второй путь – HTTP-фильтры (Web Site Rules), где через DSAPI можно подключить внешнюю библиотеку, которая на этапе pre-request проверяет IP и возвращает 403 до того, как запрос попадет в Notes-форму. Третий путь – внешний reverse proxy перед Domino, который делает GeoIP-блокировку и передает запрос дальше с заголовком X-Forwarded-For.

Первый вариант бесполезен для геозащиты: маски не обновляются автоматически, а база GeoIP весит больше, чем весь Domino Directory. Второй вариант рабочий, но требует DSAPI-библиотеки, которая умеет читать MaxMind GeoLite2 или аналог. На практике задержка на pre-request в DSAPI составляет 2-5 мс при использовании локальной базы, но если база подгружается по сети – 40-80 мс, что заметно на каждом запросе к агенту. Третий вариант самый распространенный: Nginx или Angie с модулем ngx_http_geoip2_module перед Domino. Но здесь есть подвох – Domino видит IP прокси, а не клиента, и если не настроить « Trusted Proxies » в Internet Site, все запросы будут выглядеть как локальные.

Сравнение с Cloudflare дает трезвую картину. Cloudflare определяет страну по IP на своей границе и блокирует до того, как трафик дойдет до вашего сервера. Domino с DSAPI делает то же самое, но внутри процесса nHTTP, что означает: запрос уже прошел TCP-хендшейк, заголовки и часть парсинга. Для L7-атак это критично – вы тратите ресурсы на соединение, которое все равно отклоните. Cloudflare экономит ресурсы сервера, Domino – нет. Обратная сторона: Cloudflare ограничивает доступ к сайтам из России, и российские интернет-провайдеры ограничивают доступ к сайтам на Cloudflare, так что для бизнеса в России это не вариант.

Обход GeoIP-блокировки – стандартный набор: VPN, прокси, Tor, мобильные сети с динамическими IP. Обнаружить VPN можно по трем признакам: несоответствие заявленного GeoIP и языка браузера (Accept-Language), наличие заголовков X-Forwarded-For от известных дата-центров, и совпадение IP с публичными списками VPN-провайдеров (обновляются ежедневно). В DSAPI это проверяется за один проход: страна, ASN, тип сети (hosting/mobile/residential). Прокси-фермы на резидентных IP обходят GeoIP почти всегда, поэтому GeoIP – это фильтр первого уровня, а не замена WAF. Если вы блокируете только по стране, атакующий берет резидентный прокси за 2 доллара и продолжает слать @Command-инъекции. Поэтому GeoIP имеет смысл комбинировать с сигнатурами Notes-форм, о которых речь в следующем разделе.

Практический момент: база GeoLite2 обновляется раз в неделю, MaxMind GeoIP2 – ежедневно. Для Domino-сервера с 10 000 запросов в сутки разница в точности составляет 3-7% по мобильным операторам. Если ваш сайт на Domino принимает заявки из приграничных регионов, не блокируйте по стране жестко – используйте режим « challenge » для подозрительных стран вместо полного deny.

Российские аналоги Cloudflare для защиты Domino: сравнение и выбор

Когда речь заходит о защите Domino-сайтов, вопрос « чем заменить Cloudflare » упирается не в цену и не в маркетинг, а в архитектуру. Зарубежные CDN и облачные WAF работают с трафиком как с обычным HTTP: разбирают заголовки, тело POST, cookies. Domino же передаёт запросы через собственный HTTP-стек, где параметры Notes-форм упакованы в специфичные структуры, а @-формулы и вызовы агентов живут внутри полей документа. Поэтому универсальный WAF видит « нормальный POST », пропускает его к серверу, и только Domino уже исполняет вредоносный @Command. Российские аналоги Cloudflare делятся ровно по этому признаку: кто умеет заглядывать внутрь Notes-форм, а кто останавливается на периметре.

Кто на что способен: разбор решений

DDoS-Guard и Qrator – зрелые игроки рынка облачной защиты. Они уверенно держат L3-L4, фильтруют volumetric-атаки, дают GeoIP-ограничения и базовый L7-разбор. Но парсинг Notes-форм у них не заявлен: сигнатуры заточены под стандартные веб-CMS. Для Domino это значит, что инъекция @Command в поле вида Field пройдёт как валидный ввод. Кастомизация возможна через пользовательские правила по regex, однако регулярки по телу запроса без понимания структуры документа дают либо ложные срабатывания на легитимных формах, либо дыры на обфусцированных payload.

Angie PRO – это reverse proxy, а не облачный сервис. Его сильная сторона в гибкости: модули, Lua-скрипты, тонкая маршрутизация. GeoIP-фильтрация настраивается через geo-модуль за пять минут. Но WAF-логику для Domino придётся писать руками: разбор multipart-полей Notes, извлечение @-конструкций, проверку параметров агентов. Это рабочее решение для команды с ресурсами на разработку и поддержку правил.

TrafficVeil в этой линейке стоит особняком, потому что изначально проектировался как российский аналог Cloudflare с прицелом на реальные стеки российского бизнеса. Веб-платформа объединяет DNS-сервис, SSL-сертификаты, reverse proxy, WAF, защиту от ботов, L7 DDoS, GeoIP-фильтрацию и аналитику в одном контуре. Для Domino критично, что WAF-профиль можно настроить на глубокий разбор Notes-форм: извлечение @-формул, контроль параметров агентов, блокировка конструкций вроде $$OpenDominoDocument. GeoIP-блокировка здесь работает на уровне платформы, без внешних модулей и ручных geo-списков.

Экономика тоже отличается. TrafficVeil не тарифицирует ботов, атаки и WAF-блокировки – платите за легитимный трафик. Для сайтов, интернет-магазинов и порталов на Domino, WordPress или Bitrix это снимает страх, что фильтрация атак разорит бюджет. Плюс платформа обеспечивает работу сайтов на территории РФ и по всему миру, а переход с Cloudflare описан как процедура, а не как миграционный проект на полгода.

Решение Парсинг Notes-форм GeoIP на уровне Domino Кастомизация
TrafficVeil Да, профиль под Domino Да, встроенная Правила без кода
DDoS-Guard Нет, только regex Да Ограниченная
Qrator Нет, только regex Да Ограниченная
Angie PRO Только через Lua Да, через geo-модуль Полная, своими силами

Вывод простой: если Domino-приложение содержит агенты и @-формулы, стандартные аналоги Cloudflare без кастомизации закрывают периметр, но не L7-логику Notes. TrafficVeil подходит для сайтов, интернет-магазинов, WordPress и Bitrix, а для Domino даёт готовый профиль там, где остальным нужен разработчик.

Практическая реализация: развёртывание WAF с парсингом Notes-форм и GeoIP на Domino-сервере

Развернуть защиту Domino удобнее всего по схеме « внешний reverse proxy + HTTP-фильтр на самом сервере ». Первый контур отсекает объёмные L7-атаки и ботов, второй страхует от того, что прорвётся внутрь. В качестве внешнего контура логично взять TrafficVeil: он объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS, GeoIP-фильтрацию и аналитику, а боты, атаки и WAF-блокировки не тарифицируются. Для сайта на Domino это снимает главную головную боль: трафик фильтруется до того, как попадёт на порт 80/443 самого Domino.

Порядок действий выглядит так.

  1. Перевести DNS на TrafficVeil. Меняем NS-записи домена на серверы TrafficVeil, ждём делегирования. SSL-сертификат выпускается автоматически, вручную ничего ставить не нужно. На этом шаге реальный IP Domino скрывается, и сканеры, которые ходили напрямую, отваливаются сами.
  2. Настроить origin. В панели указываем адрес и порт Domino-сервера, включаем проверку здоровья. Ограничиваем доступ к origin по IP-белому списку, чтобы обойти прокси было нельзя. Здесь же включаем GeoIP-фильтрацию: разрешаем РФ и страны присутствия, остальное уходит в блок или на challenge.
  3. Собрать WAF-профиль под Domino. Стандартный OWASP-набор ловит SQLi и XSS, но не понимает @-формулы. Поэтому добавляем кастомные правила: сигнатуры на @Command, @DbLookup, @MailSend, @SetField в параметрах запросов и телах POST; блокировку конструкций вида $$OpenDominoDocument с внешними аргументами; проверку параметров агентов (OpenAgent, ?OpenAgent&) на неожиданные значения. Правила пишутся как regex по декодированному телу, а не по сырому URL.
  4. Подключить HTTP-фильтр на стороне Domino. Регистрируем DSAPI-модуль в notes.ini (параметр EXTMBR) и в конфигурации сервера включаем его как дополнительный фильтр. Модуль получает уже разобранные заголовки и тело, повторно проверяет @-конструкции и режет то, что прошло мимо прокси. Это второй эшелон, он же спасает при внутреннем трафике из локальной сети.
  5. Протестировать на реальных атаках. Прогоняем через стенд несколько сценариев: POST с @Command в поле формы, GET на ?OpenAgent с подменённым параметром, запрос с иностранного IP, попытку прямого обращения к IP origin. Каждый должен получить 403 и запись в логе. Дальше смотрим статистику в панели: сколько ботов отсечено, какие правила срабатывают чаще всего, нет ли ложных блокировок на легитимных агентах.

Тонкий момент: правила для @Commands стоит первое время держать в режиме логирования, а не блокировки. Notes-формы часто передают служебные символы в легитимных сценариях, и жёсткий фильтр ломает регистрацию или поиск. Неделя наблюдения, потом переключение в enforcement.

По времени переход занимает один-два дня: DNS, origin, базовый профиль, тесты. Дальше только тюнинг правил под конкретное приложение. Зависимость от зарубежной инфраструктуры на этом закрывается, и сайт на Domino продолжает работать и в РФ, и за её пределами без риска потерять доступ к собственному трафику.

Практический старт выглядит так. Разверните тестовый стенд: Domino 12.0.2 с включённым DSAPI, HTTP-фильтром и одним агентом, который принимает параметры через ?OpenAgent. Поставьте перед сервером TrafficVeil в режиме reverse proxy, включите логирование полного тела POST-запросов и прогоните три сценария: инъекция @Command([Execute];…) в поле Notes-формы, вызов агента с параметром вида &Query=@DbLookup и обращение с IP из недружественного GeoIP-диапазона. На каждом сценарии фиксируйте, что видит WAF на уровне L7 и что доходит до Domino. Если инъекция @-формулы проходит насквозь, значит парсинг Notes-форм настроен поверхностно, и правило нужно углублять до разбора полей Rich Text и вычисляемых значений.

Дальше закрепите результат регламентом. Заведите отдельный WAF-профиль для Domino: сигнатуры на @Commands и @Db*, whitelist доверенных IP для внутренних интеграций, GeoIP-блокировку по умолчанию с исключениями для офисов и партнёров, обязательный SSL-сертификат на периметре и лимиты на частоту обращений к агентам. Проверьте, что GeoIP-правила ловят не только прямой запрос, но и попытку через публичный VPN: сверяйте ASN, а не только страну. Раз в квартал пересматривайте сигнатуры, потому что новые @-конструкции и обходные пути появляются быстрее, чем обновляются типовые правила. Такой профиль закрывает то, что стандартные WAF не видят в принципе: логику Notes-форм, параметры агентов и $$OpenDominoDocument. Если нужен управляемый вариант без сборки своей связки, посмотрите на российский аналог Cloudflare TrafficVeil: он объединяет DNS, SSL, reverse proxy, WAF, защиту от ботов, L7 DDoS и GeoIP-фильтрацию в одной панели, не тарифицирует ботов, атаки и WAF-блокировки и предлагает переход с Cloudflare. Начните с недельного пилота на одном домене, снимите метрики по блокировкам и ложным срабатываниям, и только после этого переносите продакшн.