Представьте сертификат, у которого впереди ещё сорок дней. Календарь спокоен, панель зелёная, напоминание о продлении не пришло. А у части посетителей браузер показывает страшную страницу с красным замком. Срок тут ни при чём: сертификат выдан на другое имя, или сервер забыл отдать промежуточный сертификат, или DNS у одного провайдера всё ещё ведёт на старый сервер со старым сертификатом. Проверка «сколько дней осталось» про всё это молчит.

Поэтому разговор о мониторинге DNS и TLS стоит начинать не с даты, а с вопроса: из каких отдельных условий складывается успешное соединение и какое из них вы сейчас проверяете. Предупреждение полезно тогда, когда по его тексту сразу понятно, что чинить: запись, доставку сертификата или его содержимое.

Три разные вещи под словом «сайт»

Когда человек говорит «сайт упал», он смешивает три сущности.

  1. Имя. Строка example.ru, которую пользователь вводит в адресную строку и которую сертификат должен подтвердить.
  2. Набор DNS-ответов. То, что вернёт конкретный рекурсивный резолвер на запрос об этом имени: A, AAAA, CNAME и так далее. У разных резолверов он может отличаться, и это не обязательно ошибка.
  3. Сервер, до которого дошёл клиент. Машина по одному из адресов из ответа, на которой в момент соединения может жить совсем не тот сайт, что вы ожидаете.

Ошибка на любом из трёх уровней выглядит для пользователя одинаково, а чинится в разных местах. Имя сломано: опечатка или потерянная запись в зоне. Набор ответов разный: кеши, TTL, незавершённая смена адреса. Сервер не тот: старый хост, забытый балансировщик, неверно настроенный виртуальный сайт. Хороший мониторинг разделяет эти уровни и в каждом случае сообщает, на каком из них проблема.

Заметьте и асимметрию. Ваш сервер видит только себя, а клиент проходит весь путь: резолвер, адрес, TCP, TLS, HTTP. Если проверять только последний шаг изнутри сети, вы увидите, что приложение живо, и не узнаете, что до него никто не добирается. Пробы нужны снаружи, и лучше с нескольких точек. Общий разбор инструментов внешней проверки доступности есть в статье про мониторинг доступности сайта; здесь мы сосредоточимся на DNS и сертификатах.

DNS-проба: что именно спрашивать

В Prometheus blackbox_exporter DNS-проба описывается отдельными параметрами: можно указать имя запроса query_name, тип записи query_type, допустимые коды ответа и условия на разделы answer, authority и additional (документация конфигурации). HTTP, TCP и DNS там настраиваются независимыми модулями. Это важное свойство: проверка DNS не должна зависеть от того, открылась ли страница, иначе вы потеряете различие между уровнями.

Набросок модуля для проверки A-записи может выглядеть так. Конкретные имена полей сверьте с релизом, который у вас установлен: документация в основной ветке меняется.

modules:
  dns_a_example:
    prober: dns
    timeout: 5s
    dns:
      query_name: "example.ru"
      query_type: "A"
      valid_rcodes:
        - NOERROR
      validate_answer_rrs:
        fail_if_none_matches_regexp:
          - "example\\.ru\\.\\s+\\d+\\s+IN\\s+A\\s+203\\.0\\.113\\.10"

Адрес 203.0.113.10 здесь из документационного диапазона и служит условным примером. Смысл проверки такой: недостаточно получить ответ без ошибки. Пустой ответ с кодом NOERROR технически успешен, но сайт по нему не откроется. Условие на содержимое answer превращает «резолвер ответил» в «резолвер ответил тем, что мы ожидаем».

Есть и обратная крайность: слишком жёсткое ожидание. Если у сайта несколько адресов, CDN или балансировка по DNS, ожидание одного конкретного IP станет источником ложных тревог. Задайте не конкретное значение, а допустимое множество: любой из ваших адресов, подсеть, нужный CNAME. Хорошее правило: проверка должна падать при реальной поломке и молчать при штатном изменении, о котором вы знаете заранее.

Срок, имя и цепочка: три независимых условия

Теперь сертификат. Обычно его сводят к дате notAfter, и это самая известная и самая узкая проверка. Клиент, устанавливая соединение, выясняет как минимум три разные вещи.

  • Срок. Действует ли сертификат сейчас. Это единственный пункт, который можно прогнозировать по календарю.
  • Имя. Входит ли запрошенное имя в список имён сертификата. Сертификат на www.example.ru отлично действует и при этом бесполезен для example.ru.
  • Цепочка. Может ли клиент построить путь от предъявленного сертификата до доверенного корня, получив от сервера нужные промежуточные звенья.

Эти условия ломаются независимо. После продления можно положить на сервер свежий листовой сертификат, но забыть цепочку: у большинства браузеров, которые умеют сами догружать промежуточные, всё будет открываться, а у API-клиентов, мобильных приложений и старых систем начнутся ошибки. Можно выпустить сертификат на новое имя и потерять прежнее. Можно перепутать файлы и подложить сертификат от соседнего проекта: срок прекрасный, имя чужое.

Разберём на условном примере, как это выглядит в проверках. После продления на сервер положили файл только с листовым сертификатом для example.ru. Проба по имени покажет нормальный срок, а проверка имени тоже пройдёт: листовой сертификат подходит. Ошибка живёт в третьем условии, и поймать её можно, только если проба строит цепочку без помощи кеша промежуточных сертификатов, который есть у браузера. Поэтому зелёный результат в браузере администратора не заменяет проверку из отдельного клиента, у которого нет накопленного кеша.

Полезно также различать, что именно сломалось, по форме симптома. Ошибка имени бьёт по всем клиентам одинаково и сразу. Ошибка цепочки избирательна: зависит от того, умеет ли клиент догружать недостающие звенья. Ошибка срока тоже одинакова для всех, но наступает в точно известный момент. Если жалобы приходят от одних приложений, а браузеры молчат, начинать стоит с состава файла сертификата на сервере, а не с продления.

В исходниках blackbox_exporter эти вещи тоже разведены: код вычисляет ближайшее истечение среди предъявленных сервером сертификатов, а проверенные цепочки, имя издателя и параметры TLS обрабатываются отдельно (TLS probe helpers). Практический вывод: «ближайшее истечение» относится ко всему набору, который отдал сервер. Если в наборе окажется промежуточный сертификат с близким сроком, предупреждение сработает раньше, чем истечёт листовой. Это полезное свойство, но в тексте тревоги стоит указывать, какой именно сертификат имеется в виду, иначе дежурный будет искать проблему не там.

Где проверка превращается в самообман

У TLS-конфигурации пробы есть список доверенных центров сертификации и проверяемое имя сервера, а параметр insecure_skip_verify полностью отключает проверку сертификата (документация конфигурации). Соблазн понятен: проба стала красной из-за внутреннего самоподписанного сертификата, флаг включили, и всё позеленело. Но вместе с ложной тревогой исчезла способность проверки замечать то, ради чего она создавалась. Зелёный результат с отключённой верификацией означает лишь «порт отвечает и по нему идёт TLS». Про имя, цепочку и доверие он не говорит ничего.

Если контролируется доверие, верификацию не отключают. Для внутренних сервисов добавляйте собственный корневой сертификат в доверенные для конкретного модуля. А если нужна только информация о сроке на сервисе с заведомо недоверенным сертификатом, заведите отдельный модуль с понятным названием и не используйте его как доказательство корректности.

Проверка по IP: можно получить правду о чужом сайте

Часто мониторинг настраивают на адрес: https://203.0.113.10/. Это кажется надёжным: нет DNS, нет кешей. Но один IP-адрес нередко обслуживает много виртуальных сайтов, и выбор между ними сервер делает по имени, которое клиент сообщает при рукопожатии (SNI), и по заголовку Host в запросе. Подключившись к голому IP без имени, вы получите сертификат по умолчанию. Это может быть сертификат совсем другого сайта, заглушки хостинга или самоподписанный. Проба либо покраснеет без причины, либо, что хуже, позеленеет на чужом сертификате с хорошим сроком и вы будете уверены, что с вашим сайтом порядок.

Корректный способ проверить конкретный сервер: подключаться к нужному адресу, но называть при этом правильное имя. В настройках TLS пробы для этого есть проверяемое имя сервера (документация конфигурации), а при ручной проверке то же делает openssl:

openssl s_client -connect 203.0.113.10:443 -servername example.ru -verify_hostname example.ru </dev/null

Так вы получаете именно тот сертификат, который увидит клиент, пришедший за example.ru на этот сервер. Такая проверка удобна, когда нужно сравнить поведение нескольких машин за одним именем: старой и новой, основной и резервной. Различие сразу показывает, на какой из них сертификат не обновили.

Разница проявляется в переходный период. Допустим, за именем example.ru стоят старый и новый серверы, а сертификат обновили только на новом. Проба по имени через DNS будет то зелёной, то красной в зависимости от того, какой адрес вернул резолвер и куда пришло соединение. Такая «мигающая» картина сбивает с толку, пока не запущены две проверки по адресам с одним и тем же именем: одна покажет свежий сертификат, другая старый, и ответ на вопрос «какой узел отстал» получается за секунды.

Обратите внимание на то, что проверяется в команде выше: ключ -servername задаёт имя для выбора виртуального сайта, а -verify_hostname заставляет клиент сверить предъявленный сертификат с этим именем. Без второго ключа вы увидите сертификат, но проверка соответствия имени не будет выполнена, и расхождение придётся замечать глазами.

Полезное разделение: проба по имени (через обычный DNS) показывает то, что видят пользователи, а проба по адресу с явным именем показывает состояние отдельного сервера. Первая отвечает на вопрос «работает ли для людей», вторая на вопрос «какой именно узел виноват». Держать нужно обе, но алертить в первую очередь по первой.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Резолверы расходятся: это ещё не авария

Вы меняете адрес сайта: переезд на новый VPS, смена провайдера. Зона обновлена, авторитетный сервер отдаёт новое значение. Вы запрашиваете запись через один публичный резолвер, получаете новый адрес; через другой старый. Первая мысль, особенно при нервной работе: что-то не так, возможно, подмена. Но в большинстве случаев это обычная работа кешей.

TTL задаёт время, на которое рекурсивные резолверы могут хранить запись; чем он длиннее, тем дольше прежнее значение остаётся в ходу, и документация Route 53 поэтому советует снижать TTL заранее, до изменения уже используемой записи (Amazon Route 53, TTL). Если TTL был 86400 секунд, то резолвер, получивший старый ответ минуту назад, имеет право отдавать его почти сутки. Расхождение между резолверами в окне после изменения ожидаемо.

Простой пример расчёта. Условно: TTL равен 3600 секунд, запись меняется в 12:00. Резолвер, закешировавший её в 11:59, будет отдавать старое значение до 12:59. Резолвер, который спросил в 12:01, сразу получит новое. В 12:30 вы увидите разнобой, и это нормально. К 13:00 все резолверы, следующие TTL, должны сойтись. Если в 13:30 один из них всё ещё отдаёт старое, вот тогда стоит разбираться, и причиной, скорее всего, окажется не взлом, а особенность конкретного резолвера, второй авторитетный сервер с неактуальной зоной или ещё один слой кеширования на пути.

Отсюда правило для тревог. Расхождение ответов резолверов само по себе не доказывает ни подмену, ни компрометацию. Оно означает одно из: кеш в пределах TTL, рассинхронизация авторитетных серверов, разные ответы по географии (если вы намеренно так настроили) или реальная проблема. Настраивайте тревогу не на «ответы различаются», а на «ответы различаются дольше, чем разрешает TTL плюс запас». Тогда тревога несёт информацию, а не шум.

Чтобы правило работало на практике, полезно вычислять окно допустимого расхождения из конкретных чисел. Пусть TTL записи равен 3600 секундам, а проверки идут раз в пять минут. Расхождение, которое держится десять минут, укладывается в нормальную работу кешей. Расхождение через час и ещё запас в пятнадцать минут уже выходит за пределы того, что объясняется кешированием. Запас нужен потому, что резолвер мог получить ответ в самый последний момент перед изменением, и его срок истекает ровно через полный TTL после смены.

Если же перед переездом TTL заранее снизили, как рекомендует документация Route 53, окно сокращается пропорционально, и порог тревоги можно сделать короче. Так одно и то же правило даёт разные пороги для разных периодов жизни записи: перед переездом с TTL 86400 ждать приходится сутки, после подготовки с TTL 300 расхождение не должно держаться дольше нескольких минут.

Само по себе различие ответов не говорит и о компрометации. Подмена записи выглядела бы иначе: неожиданное значение отдаёт авторитетный сервер или значение не совпадает ни со старым, ни с новым вашим адресом. Поэтому сравнивайте ответы не друг с другом, а с заранее известным множеством допустимых значений: старый адрес, новый адрес. Всё, что вне этого множества, заслуживает отдельной и более срочной тревоги.

Какие точки опроса брать? Хотя бы:

  • резолвер вашего хостинг-провайдера или собственный, если он есть;
  • два-три крупных публичных резолвера;
  • запрос напрямую к авторитетным серверам зоны, чтобы знать эталонное значение.

Последний пункт самый ценный. Если авторитетные серверы отвечают правильно, а резолверы ещё нет, причина во времени. Если неправильно отвечает авторитетный сервер, чинить надо запись. Так одно различие превращается в указание: ждать или править.

Как выглядит расхождение в проверках

Разбор типичных расхождений после изменения записи
Что видноВероятная причинаЧто делать
Авторитетные серверы отдают новое значение, часть резолверов старое, срок TTL не истёкКеш в пределах TTLЖдать; тревогу не поднимать
Авторитетные серверы отдают разные значенияРассинхронизация зоны между серверами имёнИсправлять распространение зоны у DNS-провайдера
Все резолверы отдают новое значение, но сертификат у части клиентов старыйЧасть трафика попала на сервер без нового сертификатаПроверять каждый узел по IP с явным именем
Новое значение везде, сертификат корректен, клиенты жалуются на цепочкуНе отдаётся промежуточный сертификатИсправлять состав файла сертификата на сервере

Последние две строки показывают, почему DNS и TLS лучше мониторить вместе: после смены адреса сертификатные проблемы проявляются именно в окне, когда часть клиентов ещё идёт на старый узел, а часть на новый.

Периодичность и уровни: сколько у вас времени на исправление

Теперь о частоте и порогах. Универсальных чисел здесь нет, и ориентироваться стоит на единственный вопрос: сколько времени нужно человеку, чтобы исправить именно эту ошибку, и через сколько она начнёт бить по пользователям.

Разные условия живут в разных временных масштабах.

  • Срок сертификата меняется медленно и предсказуемо, но исправление может требовать согласований, доступа к центру сертификации и деплоя. Порогов нужно несколько: раннее информационное, затем повышение срочности. Условный пример: уведомление за 30 дней, предупреждение за 14, срочное за 5 и аварийное за 2. Разумность цифр определяется тем, за сколько вы реально успеваете: если выпуск требует недели из-за процессов, тридцать дней это не перестраховка, а минимум.
  • Имя и цепочка ломаются в момент изменения: деплоя, смены файла, переезда. Проверять их стоит часто, раз в несколько минут, потому что ошибка начинает действовать сразу, а время на исправление измеряется минутами.
  • DNS-ответы важны в окне после изменений и значительно меньше в обычное время. Здесь логично повышать частоту опроса на период смены записи и возвращать обратно после сходимости.

Отдельно о защите от шума. Одиночный сбой пробы (сетевая потеря, таймаут) не должен будить человека. Требуйте, чтобы условие держалось несколько подряд идущих проверок, а для DNS-расхождений добавляйте запас сверх TTL. Чем быстрее вредит ошибка, тем короче задержка перед тревогой; чем медленнее и предсказуемее процесс, тем больше уровней и тем мягче первые из них.

Тексты предупреждений тоже часть дизайна. Сравните два сообщения: «TLS probe failed» и «example.ru: сертификат не подходит по имени; сервер 203.0.113.10 отдал сертификат для other.example.ru». Второе содержит ответ на вопрос, куда смотреть. Включайте в тревогу: проверяемое имя, адрес, к которому подключались, какой резолвер дал этот адрес, какое условие нарушено (срок, имя, цепочка) и какое значение ожидалось.

Где запускать проверки и что им нужно от сервера

Сами проверки лёгкие: короткие DNS-запросы и рукопожатия, ничего вычислительно тяжёлого. Поэтому небольшая виртуальная машина вполне подходит для роли внешнего наблюдателя, который запускает blackbox_exporter и опрашивает ваши сервисы по расписанию. Главное требование к ней не мощность, а независимость: проверяющий узел не должен стоять там же, где сайт, и использовать те же сетевые пути, иначе при общей аварии замолчат и сайт, и мониторинг. Размещение разных проб в разных локациях даёт ещё и сравнение «как видно оттуда».

На VPS MAATRIX, где есть root-доступ, NVMe и выбор локаций (в публичном предложении указаны UK, US, RU и FR), можно развернуть такой наблюдатель отдельно от основной площадки, а при желании держать пару пробных узлов в разных странах. Тарифы Ba с 1 vCPU и 2 ГБ RAM и выше перечислены на странице аренды VPS; подходящий размер зависит от числа целей и частоты опроса, и его стоит определять по собственным измерениям, а не по таблице ресурсов. Наличие образов и ОС в конкретной локации уточняйте в форме заказа.

Что должно оставаться в голове у дежурного

Соберём логику разбора, которую стоит заложить в тексты и описания проб. Если тревога говорит об ответе DNS, смотрим авторитетные серверы: ошибка там значит, что править надо запись; если там всё верно, а различаются только резолверы, сверяем время с TTL и ждём либо ищем рассинхронизацию. Если DNS в порядке, но соединение с каким-то узлом даёт неверный сертификат, значит, на этом узле не доставлен нужный файл или виртуальный сайт выбран неправильно, то есть чинится доставка сертификата и настройка сервера. Если узел отдаёт верный набор, а клиенты жалуются на доверие, проверяем содержимое: имена в сертификате, промежуточные звенья, срок каждого звена.

Итоговое предупреждение, ради которого всё затевалось, должно звучать примерно так: «Для example.ru три резолвера из четырёх возвращают новый адрес, четвёртый старый уже дольше TTL; на новом адресе сертификат корректен, на старом выдан на другое имя. Исправляйте запись у резолвера или вывод старого узла из ответа, но не продлевайте сертификат: срок тут ни при чём». Такое сообщение не требует расследования: из него ясно, какой элемент ломается — запись, доставка сертификата или его содержимое, — и дежурный идёт прямо к нему.