MAATRIX / Блог / Кто-то выпустил сертификат на ваш домен: как это увидеть

Кто-то выпустил сертификат на ваш домен: как это увидеть

MAATRIX

Однажды вы заходите в поисковик по логам Certificate Transparency просто из любопытства — и видите сертификат на свой домен, выпущенный удостоверяющим центром, с которым вы никогда не работали, для поддомена, который никто в команде не помнит. Это может быть безобидная история: старый CDN, забытый тестовый стенд, партнёр, который когда-то настраивал вам поддомен. А может быть и признак того, что кто-то получил контроль над частью вашей DNS-зоны или веб-инфраструктуры и тихо выпустил себе валидный сертификат — чтобы перехватывать трафик, а не ломать сайт напролом. Разница между этими сценариями видна только если вы вообще смотрите в CT-логи. Разберём, как это делать регулярно, а не постфактум.

Что такое Certificate Transparency и почему это вообще возможно увидеть

Certificate Transparency (CT) — это открытая инфраструктура публичных, добавляемых-только-в-конец журналов (append-only logs), в которые удостоверяющие центры обязаны отправлять данные о каждом выпущенном TLS-сертификате: домен (Common Name и все альтернативные имена — SAN), удостоверяющий центр-эмитент, даты выпуска и истечения, серийный номер. Идея появилась после нескольких громких инцидентов начала 2010-х, когда центры сертификации выпускали сертификаты на чужие домены — по ошибке, из-за взлома или под давлением — и никто из владельцев доменов об этом не узнавал месяцами.

С тех пор правила ужесточились радикально: современные браузеры (первым это потребовал Chrome) отказываются доверять публичному TLS-сертификату, если для него нет доказательства включения хотя бы в два независимых CT-лога — это называется SCT, Signed Certificate Timestamp (формально RFC 6962 и его развитие). Практический эффект простой: если для вашего домена выпущен сертификат, которому будут доверять браузеры, он почти наверняка попал в CT-логи — и это публично читаемая, неизменяемая история выпуска (записи нельзя тихо удалить задним числом — структура лога построена как дерево Меркла именно для этого).

Важное ограничение: CT-логи фиксируют TLS-сертификаты для HTTPS и подобных протоколов. Они ничего не говорят о выпуске, например, S/MIME-сертификатов для почты или клиентских сертификатов внутренней PKI — это отдельная история, вне темы статьи.

Как искать записи по своему домену в CT-логах

Записи CT-логов в чистом виде — это протокольные структуры, читать их напрямую неудобно и не нужно: для этого существуют публичные поисковики, которые сами агрегируют данные из десятков логов от разных операторов (Google, Let's Encrypt, DigiCert, Sectigo и другие ведут собственные независимые логи) и дают простой поиск по имени домена. Самый известный и старый из таких сервисов — crt.sh, есть и другие с похожей функцией, включая инструмент поиска по CT-логам от самого Google. Вводите домен — получаете список всех сертификатов, где он фигурирует как CN или SAN, с эмитентом и датами.

Что стоит смотреть в результатах:

  • Эмитент (Issuer). Если вы работаете только с Let's Encrypt через certbot/acme.sh на своих серверах и вдруг видите запись от совсем другого CA — это первый сигнал присмотреться.
  • Список SAN целиком, а не только запрошенный домен. Один сертификат часто выпускается сразу на несколько имён. Если в SAN затесался поддомен, который вы не создавали — admin.example.com, vpn.example.com, old-crm.example.com — стоит проверить, существует ли вообще такая DNS-запись и куда она указывает.
  • Дату выпуска относительно ваших собственных изменений. Сертификат, выпущенный за пару часов до или после того, как вы меняли DNS-записи, NS-делегирование или доступ у регистратора, заслуживает отдельного внимания — совпадение может быть случайным, а может и не быть.
  • **Wildcard-сертификаты (*.example.com).** Их выпуск возможен только через DNS-01 challenge (см. статью о том, как Let's Encrypt доказывает владение доменом) — а значит, если вы такой сертификат не заказывали, кто-то смог временно писать в вашу DNS-зону, что серьёзнее, чем разовый взлом одного поддомена.

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

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

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

Арендовать сервер

Когда чужой сертификат — это симптом компрометации, а не шум

Сертификат для вашего домена не может быть выпущен без прохождения проверки владения (DCV, Domain Control Validation) — CA обязан её выполнить по правилам CA/Browser Forum. Значит, если в CT-логе всплыл сертификат, который выпустили не вы, кто-то прошёл эту проверку вместо вас. Практически это означает один из сценариев:

  • Захват контроля над DNS-зоной. Взломан аккаунт у регистратора или DNS-провайдера, злоумышленник добавил TXT-запись для DNS-01 challenge, получил сертификат и, возможно, откатил изменение — в самой зоне следов может почти не остаться, а сертификат в CT-логе останется навсегда.
  • Захват веб-сервера или прокси перед ним. Для HTTP-01 challenge достаточно на несколько секунд ответить нужным файлом по конкретному пути — это делает возможным выпуск через скомпрометированный балансировщик или реверс-прокси, даже без полного захвата основного сервера.
  • Устаревшая делегация поддомена. Классическая история subdomain takeover: DNS-запись когда-то указывала на внешний сервис (облачный storage, старый SaaS, брошенный инстанс у хостинг-провайдера), сервис удалили, а запись в DNS забыли. Тот, кто первым заберёт себе освободившийся ресурс с тем же именем, может пройти DCV и получить валидный сертификат на ваш поддомен — с этого момента фишинговая страница на promo.example.com будет выглядеть для браузера абсолютно легитимно, с зелёным замком.
  • Слабое звено у подрядчика или бывшего сотрудника. Доступ к DNS или хостингу, который давно пора было отозвать, но не отозвали — не взлом в классическом смысле, а забытая дверь.

Ключевой вывод: сертификат в CT-логе, который вы не заказывали, — это не сам инцидент, а его следствие и одновременно самый ранний внешний индикатор, который у вас вообще есть, потому что взлом DNS или прокси сам по себе может не оставить заметных логов на вашей стороне.

Проактивный мониторинг: не искать руками, а получать алерт

Ручной поиск раз в месяц — лучше, чем ничего, но между вашими проверками может пройти немало времени, а фишинговый сайт на чужом поддомене с валидным сертификатом живёт обычно не месяцами, а днями или часами, пока его не заметят и не заблокируют. Задача — сократить это окно с помощью периодической автоматической проверки.

Практический вариант — простой скрипт по расписанию, который запрашивает у поискового сервиса по CT-логам список сертификатов для домена (многие сервисы отдают результат в том числе в JSON — конкретный формат запроса стоит свериться в документации, она может со временем меняться) и сравнивает его с сохранённым списком известных серийных номеров с прошлого запуска. Разница — то, что появилось нового, и именно по ней стоит слать уведомление.

Псевдокод логики без привязки к конкретному API:

#!/usr/bin/env bash
# ct-watch.sh — проверка новых сертификатов по домену
DOMAIN="example.com"
STATE_FILE="/var/lib/ct-watch/${DOMAIN}.known"
NEW_FILE=$(mktemp)

# 1. Получить текущий список серийных номеров сертификатов для домена
#    (конкретный запрос зависит от выбранного CT-поисковика и его API)
curl -s "https://<ct-search-service>/api?domain=${DOMAIN}&output=json" \
  | jq -r '.[] | .serial_number' | sort -u > "$NEW_FILE"

touch "$STATE_FILE"
DIFF=$(comm -13 "$STATE_FILE" "$NEW_FILE")

if [ -n "$DIFF" ]; then
  echo "Новые сертификаты для ${DOMAIN}: $DIFF" | \
    curl -s -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
      -d chat_id=<CHAT_ID> --data-urlencode text@-
fi

mv "$NEW_FILE" "$STATE_FILE"

Ставите такой скрипт в cron раз в 15-30 минут на своём VPS (задержка появления новой записи в агрегаторах поверх самих CT-логов обычно измеряется минутами, но точный интервал зависит от сервиса-источника) — и алерт приходит существенно раньше, чем вы случайно наткнётесь на подозрительную запись сами. Держите скрипт и накопленное состояние на отдельном сервере, а не на том же хосте, чей домен вы мониторите: если скомпрометирован именно основной сервер, вы хотите узнать об этом с независимой площадки.

Более зрелый вариант — не писать скрипт с нуля, а расширить уже существующий у вас мониторинг алертом именно на CT-события: если у вас уже настроен мониторинг сертификатов и доменов на предмет истечения срока действия, проверка "не появился ли неожиданный сертификат" логически укладывается в тот же процесс, вместо отдельного изолированного инструмента.

CAA-запись: кто вообще имеет право выпускать сертификат для вашего домена

CT-логи решают задачу обнаружения постфактум. CAA (Certification Authority Authorization, RFC 8659) решает смежную, но другую задачу — заранее сужает круг тех, кто в принципе может законно выпустить сертификат для домена. Это обычная DNS-запись типа CAA, и с 2017 года все публично доверяемые CA обязаны проверять её перед выпуском: если в CAA явно не указано, что этому CA разрешено выпускать сертификаты для домена, выпуск должен быть отклонён.

Синтаксис записи: флаг, тег, значение.

example.com.   CAA 0 issue "letsencrypt.org"
example.com.   CAA 0 issue "pki.goog"
example.com.   CAA 0 issuewild ";"
example.com.   CAA 0 iodef "mailto:security@example.com"

Разбор тегов:

ТегЗначение
issueКаким CA разрешено выпускать обычные (не wildcard) сертификаты для этого домена
issuewildТо же самое, но для wildcard-сертификатов (*.example.com); значение ";" означает "никому не разрешено"
iodefКуда CA должен отправить уведомление, если получил запрос на выпуск в нарушение политики (не все CA это поддерживают, но добросовестные — как правило, да)

В примере выше разрешены только Let's Encrypt и Google Trust Services — если завтра кто-то (в том числе злоумышленник, прошедший DCV через захваченный поддомен) попробует заказать сертификат у любого другого публичного CA, добросовестный удостоверяющий центр обязан отказать ещё до всякой проверки владения доменом. Если у вас несколько поддоменов на разных CA или CDN, добавляйте по отдельной issue-строке на каждого — записи складываются, а не перезаписывают друг друга.

Проверить текущее состояние записи просто:

dig CAA example.com +short

Если ответ пустой — CAA-записи нет вообще, и выпуск сертификата разрешён любому публичному CA без ограничений с вашей стороны — это состояние по умолчанию для подавляющего большинства доменов, которые никто специально не настраивал.

Важное ограничение, о котором стоит сказать честно: CAA не защищает от сценария, где злоумышленник получил полный контроль над вашей DNS-зоной — он может временно поменять и саму CAA-запись, выпустить сертификат у любого CA, а затем откатить запись обратно. CAA защищает от более узкого, но частого на практике случая: DCV прошла через отдельный, не полностью скомпрометированный канал (например, захваченный только HTTP-01 challenge на конкретном поддомене), а полного контроля над зоной у атакующего нет. В сочетании с DNSSEC (см. как DNSSEC доказывает подлинность ответа) CAA становится ощутимо надёжнее — подмена самой записи с CAA требует ещё и доказуемо валидной подписи.

Как собрать это в рабочий процесс, а не разовую проверку

По отдельности CT-мониторинг и CAA-запись закрывают разные половины задачи: CAA снижает вероятность несанкционированного выпуска заранее, CT-алерт ловит то, что всё-таки произошло — включая случаи, не покрытые CAA (захват всей DNS-зоны, устаревшая делегация поддомена, человеческий фактор внутри разрешённого CA). Рабочий процесс, который имеет смысл держать постоянно:

  1. Настройте CAA-запись на все домены и поддомены, где вы контролируете DNS-зону — сначала в разрешительном режиме (перечислите всех CA, которыми реально пользуетесь), затем время от времени пересматривайте список.
  2. Заведите отдельный iodef-адрес для уведомлений о нарушениях — почтовый ящик, который реально кто-то читает, а не общий info@, куда падает весь спам.
  3. Поставьте автоматическую проверку CT-логов по расписанию (скрипт из раздела выше или готовый сервис) для основного домена и всех продуктовых поддоменов, о которых вы знаете.
  4. Раз в квартал сверяйте список поддоменов в DNS-зоне со списком реально используемых сервисов — забытая делегация на давно удалённый внешний ресурс это именно то, что превращает subdomain takeover из теории в практику.
  5. Держите инфраструктуру мониторинга отдельно от того, что мониторите — если весь стек, включая CT-скрипт и хранение CAA-конфигурации, лежит на одном сервере, компрометация этого сервера гасит и защиту, и обнаружение одновременно.

Если вы уже проходили общий чек-лист безопасности нового сервера, пункты про CAA и CT-мониторинг стоит добавить туда же отдельными строками — это не разовая настройка "включил и забыл", а процесс, который нужно поддерживать по мере того, как появляются новые поддомены и сервисы.

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

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

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

CAA-запись гарантирует, что никто не выпустит сертификат на мой домен?

Нет. Она обязывает добросовестные публичные CA отказывать в выпуске без явного разрешения — но не защищает от полного захвата DNS-зоны (тогда атакующий поменяет и саму CAA-запись) и не действует на CA, которые правила игнорируют или которых заставили нарушить процедуру.

Если я не настраивал CAA, это уже проблема?

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

CT-логи можно как-то "почистить" от старого мусорного сертификата?

Нет, логи append-only по конструкции — записи нельзя удалить задним числом, это и есть их смысл. Если сертификат скомпрометирован или выпущен по ошибке, правильное действие — отозвать его (revoke) у CA, а не пытаться убрать из истории, убрать из истории и не получится.

Нужно ли мониторить CT-логи, если я вообще не работаю с публичным HTTPS напрямую, а всё за CDN?

Да, если за доменом стоит внешний трафик — CDN обычно сам получает сертификаты на ваш домен через собственную интеграцию, и легитимный шум от этого нормален, но это не отменяет риска, что кто-то ещё, помимо CDN, тоже пройдёт DCV в обход вас.

Достаточно ли одного публичного CT-поисковика или нужно сверяться с несколькими?

Разные поисковики опираются на разные наборы CT-логов и могут обновляться с разной задержкой, поэтому для критичных доменов разумно свериться в двух независимых сервисах хотя бы один раз, а для регулярного мониторинга выбрать тот, у которого есть удобный API для автоматизации.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →