
Привет, Хабр! Делюсь ниже статьей моего коллеги, Алексея Евсеева, который работает инженером технической поддержки в К2 Кибербезопасность в составе Центра экспертизы по комплексному сервису К2Тех и занимается администрированием средств защиты информации. Уже несколько лет он поддерживает Check Point в самых разных инсталляциях, от офисных шлюзов до крупных кластеров, и примерно раз в два-три месяца решает тикеты типа: «правило с доменом не работает», «сайт открывается через раз».
Свежий случай — месяц мучений из-за прерывистого доступа к одному крупному государственному сервису — сподвиг его написать отдельную статью про доменные объекты. Так что давайте разберемся, как устроены изнутри доменные объекты Check Point, чем FQDN отличается от non-FQDN, при чем тут DNS Passive Learning и почему штатная работа этих механизмов порой вызывает массу проблем на практике. Передаю слово Алексею.
Зачем вообще нужны доменные объекты
Все знают, что такое IP, но в современных инфраструктурах постоянный адрес — это уже, в общем-то, редкость. Облака, CDN, балансировщики постоянно меняют свои адреса, и писать правила доступа на конкретные IP в таких условиях — значит бесконечно их править и все равно наблюдать регулярные поломки.
Доменный объект нужен, чтобы переложить работу по разграничению доступов на шлюз: в правиле прописывается имя, а на какой IP-адрес разрешить или запретить отправку пакетов прямо сейчас, шлюз решает самостоятельно. Других способов стабильно работать с постоянно переезжающими сервисами по большому счету нет.
В SmartConsole все выглядит просто: создаешь объект, вписываешь имя, (не)проставляешь галочку FQDN — и готово. Однако доменные объекты Check Point — это не очень прозрачный механизм, и чтобы разобраться, откуда берутся ошибки в его работе, нужно понять, что именно включает и выключает та самая галочка.

FQDN и с чем его едят
Включение FQDN переводит шлюз в режим работы, где он становится DNS-клиентом: берет имя из объекта и получает у DNS-сервера нужный адрес. Практически так же это работает в обычном браузере. В определенный интервал времени шлюз отправляет A-запрос по каждому FQDN-объекту на все настроенные DNS-серверы и складывает пары «имя → IP» в forward-кэш.
Когда пакет уходит на какой-то адрес, шлюз сверяется с кэшем: закреплен ли этот IP за доменом из правила? Если адрес среди закэшированных ответов, правило срабатывает, и трафик идет. Если сервис переехал на новый адрес, то шлюз подхватит его при следующем опросе, в пределах минуты.
Для FQDN имя пишется с точкой в начале: .www.example.com и, соответственно, сработает только для www.example.com. Но non-FQDN-объект совпадает не только с самим доменом, но и со всеми его поддоменами вплоть до 10 уровней. То есть .example.com покрывает www.example.com, ftp.example.com, mail.support.example.com и так далее. Это удобно, когда нужно разрешить ресурс целиком, не перечисляя многочисленные поддомены вручную.


При non-FQDN шлюз фиксирует, что пакет уходит на некий IP, и спрашивает у DNS: «Какое имя стоит за этим адресом?», — то есть делает обратный PTR-запрос. Затем шлюз сравнивает ответ с доменом объекта, и если домен совпал, пропускает трафик. Проверка происходит на каждом новом соединении, так что для работы non-FQDN нужно больше ресурсов, чем для FQDN. Updatable Objects, внутри которых находятся non-FQDN-домены, могут заметно просаживать производительность шлюза (sk162577): так бывает редко, но если есть тормоза — стоит проверить политику на такие объекты. А еще non-FQDN-объекты нельзя использовать в NAT-правилах. Для таких задач лучше смотреть в сторону прокси.
Однако если прямую A-запись своего домена контролирует владелец сервиса, то обратной зоной распоряжается тот, кому принадлежат IP-адреса, — обычно это хостер или провайдер. Завести уникальную PTR-запись на каждый адрес из своих диапазонов провайдер зачастую физически не может, поэтому ставит общие. И если общая PTR-запись меняется от запроса к запросу, поведение шлюза тоже меняется: сегодня обратка вернула example.com и запрос прошел, а завтра тот же IP называется cloud.example.net, и правило не срабатывает. За жалобами «то работает, то нет» почти всегда стоит именно non-FQDN.
Поэтому первым делом я рекомендую заказчикам включать FQDN, за исключением случаев, когда действительно нужны все поддомены разом и с обратными записями у ресурса точно полный порядок. Перевод объекта на FQDN, кстати, спокойно делается на живой системе, без окна обслуживания. Я обычно мигрирую в два этапа: сначала создаю новый FQDN-объект и ставлю его в правиле ниже старого с non-FQDN — трафик пока идет по-старому, а новый объект только собирает статистику. Убедившись по логам, что новые правила матчатся как надо, меняю правила местами и удаляю старый объект.
Что лежит в кэше, и кто им управляет
После установки политики шлюз создает в памяти несколько таблиц. Forward-кэш хранит пары «домен → IP» для FQDN-объектов. Reverse-кэш собирает результаты PTR-запросов для non-FQDN (dns_reverse_cache_tbl). Отдельно создается еще и dns_reverse_unmatched_cache: туда попадают IP-адреса, не совпавшие ни с одним доменным объектом политики.
Кроме того, существует таблица dns_reverse_domains_tbl. Она содержит список доменных имен из объектов политики, с которыми сравниваются результаты PTR. Иногда бывает полезно туда залезть и посмотреть, что шлюз пытался смэтчить, но не смог:
fw ctl multik print_bl dns_reverse_cache_tbl -u fw ctl multik print_bl dns_reverse_unmatched_cache -u fw ctl multik print_bl dns_reverse_domains_tbl -u

По умолчанию эти данные хранятся 60 минут, и TTL, выставленный DNS-сервером, на это значение не влияет. Лимит составляет 25 тысяч записей, и при заполнении кэша старые строки вытесняются. Кэш обновляется раз в минуту, и при поступлении трафика шлюз опрашивает все настроенные DNS-серверы по каждому FQDN-домену из политики. Управляет всем этим хозяйством отдельный демон — WSDNSD, который читает список DNS-серверов только при старте.
DNS Passive Learning
Минутный цикл опроса покрывает не все, поэтому с R80.40 в шлюзе по умолчанию работает DNS Passive Learning (DPL).
В этом режиме шлюз перестает полагаться только на собственные запросы и начинает анализировать DNS-трафик, который через него проходит. Клиент получил ответ «portal.company.ru = 1.2.3.4», а шлюз сохранил эту пару в свой кэш. Обновление происходит за миллисекунды вместо минуты, а DNS-серверы больше не получают от шлюза запрос на каждый домен раз в минуту. Это помогает отслеживать non-FQDN-объекты, Updatable Objects (в кэш попадают только реально запрашиваемые адреса) и домены с коротким TTL, расположенные за балансировщиками. Режим задается параметром ядра dns_data_src_enabled:
Значение | Что делает |
0 | DPL выключен |
1 | non-FQDN и Updatable Objects (значение по умолчанию с R80.40) |
2 | Только non-FQDN |
3 | Все типы: non-FQDN, FQDN, Updatable Objects |
Третий режим включают, когда нужно, чтобы DPL обновлял и FQDN-объекты:
fw ctl set int dns_data_src_enabled 3 # на каждом узле кластера fw ctl set -f int dns_data_src_enabled 3 # сохранить после перезагрузки fw ctl get int dns_data_src_enabled # проверить текущее значение

Важно помнить, что это значение должно совпадать на всех узлах кластера, а синхронизация кэшей между узлами появилась только с версии R81.10. Кроме того, у этого механизма есть одно естественное ограничение. Трафик, идущий в обход шлюза, подслушать не получится, и шлюз учитывает только ответы доверенных DNS-серверов, то есть явно известных ему. Чужие серверы приходится добавлять вручную через меню: Host-объект, в свойствах на вкладке Servers галочка DNS Server, установка политики. Вариант fw ctl set int dns_data_src_allow_all_dns 1 тоже существует, но он означает «верить всем DNS-ответам подряд» со всеми вытекающими рисками подделки ответов.
Месяц возни с одним доменом
Теперь, когда мы разобрали матчасть, расскажу кейс, в котором описанные механизмы создали массу неудобств нашему заказчику на пустом месте.
В начале весны заказчик завел тикет с жалобой на то, что не открывается rosstat.gov.ru. Трафик блокировался, хотя в политике было отдельное разрешающее правило (назначим ему № 31) с доменным объектом.
До обращения проблему «чинили» самыми разными способами: включали и отключали правила, меняли их порядок, создавали уточняющие, а иногда она проходила сама. В итоге заказчик создал более явное правило № 31, и доступ ожил. Вот только в логах трафик по-прежнему шел через старое правило № 30, а новое правило будто оставалось незамеченным. В тикете так и стояли два вопроса: почему доступ перестал работать при разрешающем правиле и почему заработал после добавления другого?
Заказчик попался из тех, кто хочет посмотреть и понять, как оно устроено под капотом, так что мы стали разбираться.
Просмотр логов дал первую зацепку: reject блокировал именно rosstat.gov.ru, а соединения к www.rosstat.gov.ru проходили. Объект в правиле находился в режиме non-FQDN, а значит, шлюз определял принадлежность адреса через обратный DNS. Вместо самого имени он резолвил PTR-запись для адреса назначения, что-нибудь вроде 60.89.226.194.in-addr.arpa.
Утилита domains_tool показала, что обратный запрос для проблемного адреса возвращал имя вида server-xxx.cloud-provider.net — то есть чужое имя из диапазона хостинг-провайдера. Шлюз честно сравнивал его с .rosstat.gov.ru, совпадения не находил и блокировал трафик. Обратные ответы менялись от запроса к запросу, время от времени имена все-таки совпадали — и сайт ненадолго оживал.
Самодиагностика шлюза, как выяснилось, все это время исправно сигналила: «Test Non-FQDN Objects finished with result WARNING» и «Domain Objects — DNS Passive Learning … WARNING».

Второе предупреждение и дало нам окончательное объяснение ситуации. Оказывается, пассивное обучение работало вполсилу, потому что в DNS-трафике встречались ответы от недоверенных серверов. Внутренние DNS-серверы заказчика форвардили запросы на провайдерские, а провайдерские были неизвестны шлюзу. DPL видел их ответы и отбрасывал.

Очевидное решение — перевести проблемные домены на FQDN-объекты, но оно здесь не подходило, так как перечислить все дочерние домены госресурсов фактически невозможно. Так что в итоге нам пришлось пометить провайдерские DNS-серверы как доверенные. В результате DPL начал принимать прямые ответы, кэш стал наполняться парами «домен → IP», и обратные запросы перестали быть единственным источником истины. На решение ушло несколько часов чистой работы инженера и всего два адреса в списке доверенных серверов.
Еще две доменные кулстори
Корпоративный портал периодически зависал на 30–50 секунд, а потом снова работал как ни в чем не бывало, и так по несколько раз в день.
Оказалось, что портал стоял за балансировщиком, который часто переключал IP между узлами. У записи в DNS был выставлен TTL в 30 секунд, чтобы клиенты быстро узнавали новый адрес, а вот шлюз переспрашивал DNS раз в минуту и после каждой смены адреса какое-то время продолжал слать трафик на старый.
Вылечилось это включением DNS Passive Learning для всех типов объектов: шлюз начал перехватывать DNS-ответы, которые получали компьютеры сотрудников, и стал обновлять кэш мгновенно. Доступ стал восстанавливаться за пару секунд, и жалобы прекратились. В другом запомнившемся мне случае заказчик сменил DNS-сервер в настройках Gaia: добавил новый и убрал старый, однако домены продолжили разрешаться по-старому, как будто никто ничего не менял.
Разгадка была в особенности WSDNSD, о которой я упоминал выше: демон читает список DNS-серверов только при старте, и он не мог подхватить изменения в /etc/resolv.conf на лету. Чтобы исправить ситуацию, потребовалось всего несколько команд для перезапуска демона:
cpwd_admin stop -name WSDNSD -path "$FWDIR/bin/wsdnsd" -command "fw kill wsdnsd" cpwd_admin start -name WSDNSD -path "$FWDIR/bin/wsdnsd" -command "wsdnsd" cpwd_admin list | grep WSDNSD # статус E -- демон работает

Как узнать, что на уме у шлюза
Какие бы проблемы с доменными объектами Check Point мы ни разбирали, все сводится к тому, что на самом деле записано в памяти шлюза. Чтобы заглянуть туда, достаточно утилиты domains_tool и знания нескольких команд. Она доступна в Expert mode и работает только с IPv4. Как правило, расследование начинается с запроса «какие адреса у этого домена?». Если в ответе пусто, а объект в политике точно есть, то мы добавляем ключ -m: тогда тулза прочесывает весь кэш целиком — это медленнее, зато она ничего не пропустит.
domains_tool -d internal.corp domains_tool -d internal.corp -m
Второй вопрос — обратный: «какому домену принадлежит этот адрес?». Он помогает, когда в логах всплыл подозрительный IP и нужно понять, к какому домену и объекту политики он привязан. domains_tool -ip 203.0.113.45
Бывает, зайти нужно со стороны объекта. domains_tool -o <домен> показывает, в каких объектах политики участвует домен. Когда доменов сразу несколько, на R82 и новее их перечисляют одной командой — domains_tool -md <домен1> <домен2>. Для NAT-сценариев адрес отдает domains_tool -dx <домен>, а проверить, работает ли WSDNSD, помогает domains_tool -hc.

Отдельная история — Updatable Objects. Чтобы увидеть, что там внутри, мы запрашиваем объект по имени:
domains_tool -uo "Office365 Worldwide Services"
Пустой вывод значит одно из двух: либо объект не используется в политике, либо он не обновился. Во втором случае полезно заглянуть в сами файлы — они лежат в $CPDIR/database/downloads/ONLINE_SERVICES.
Команда domains_tool -report прогоняет проверку политики и DNS:
Сообщение | Что случилось | Что делать |
No Domain or Updatable or Network Feed object in policy | В политике нет доменных объектов | Убедиться, что объекты добавлены и политика установлена |
Cannot access DNS servers | Шлюз вообще не может достучаться до DNS (nslookup тоже не работает) | Проверить настройки DNS в Gaia, сетевую доступность серверов и не блокирует ли шлюз сам себе DNS-трафик |
WSDNSD and DNS servers are not synchronized | WSDNSD не резолвит, хотя nslookup работает | Перезапустить WSDNSD |
Process WSDNSD is not running | Демон упал | Запустить: cpwd_admin start -name WSDNSD -path “$FWDIR/bin/wsdnsd” -command “wsdnsd” |
You have Domain or Updatable Objects in policy but DNS Passive Learning (DPL) is disabled | DPL выключен при наличии доменных объектов | Включить DPL |
Undefined DNS servers found | Шлюз видит DNS-запросы к серверу, который не отмечен доверенным | Добавить Host-объект с типом DNS Server или, осознавая риски, разрешить всех через dns_data_src_allow_all_dns 1 |
Здесь важно помнить, что ключ -extended запускает tcpdump на всех интерфейсах на 60 секунд и поэтому заметно нагружает CPU, так что стоит использовать его обдуманно и только по необходимости.

Чек-лист для быстрой диагностики
Проверяем, что в кэше: domains_tool -d <проблемный домен>.
Смотрим, к какому домену привязан IP из логов: domains_tool -ip <адрес>.
Оцениваем состояние WSDNSD: domains_tool -hc и cpwd_admin list | grep WSDNSD.
Снимаем общий отчет: domains_tool -report (при необходимости — с -extended).
Проверяем режим пассивного обучения: fw ctl get int dns_data_src_enabled.
Для non-FQDN-объектов заглядываем в fw ctl multik print_bl dns_reverse_unmatched_cache -u.
В большинстве кейсов из этой статьи диагноз ставился уже на первом-втором шаге.
Заключение, или незаметная машинерия
Итак, доменные объекты Check Point и настройки FQDN в SmartConsole — это всего лишь удобные абстракции, за которыми спрятаны прямой и обратный кэш со своим TTL, минутный таймер опроса, демон, который читает конфигурацию, пассивное обучение со списком доверенных серверов и чужие PTR-записи.
И когда правила в политике безопасности начинают капризничать, менять их порядок и плодить дубли бесполезно. На первом этапе так делают почти все, и почти всегда это лотерея. Куда проще узнать, что шлюз держит в кэше и какие имена он резолвит: domains_tool и пара служебных таблиц отвечают на этот вопрос за минуту. И стоит один раз разобраться в работе этих механизмов, как вы будете знать, куда смотреть, если что-то снова пойдет не так.
Дополнительные источники по теме:

