Как отзывают сертификат и почему отозванный ещё несколько дней работает
Сертификат скомпрометирован, домен сменил владельца, приватный ключ засветился в публичном репозитории — вы идёте в панель удостоверяющего центра и жмёте «отозвать», ожидая, что через минуту сайт с этим сертификатом перестанет открываться. На практике браузеры и клиенты ещё какое-то время продолжают доверять отозванному сертификату, будто отзыва не было. Это не баг конкретного CA и не чья-то небрежность — так устроены оба механизма проверки отзыва, CRL и OCSP, и у каждого есть встроенная задержка, о которой полезно знать заранее, а не в момент, когда она внезапно оказывается важна.
Содержание
- Зачем вообще отзывают сертификат
- CRL: список, который нужно скачать целиком
- OCSP: спросить именно про этот сертификат
- OCSP stapling: сервер приносит ответ заранее — и тоже кеширует его
- Мягкий провал: если проверку не удалось выполнить, доверяем по умолчанию
- Сколько это реально занимает — часы, дни, а не секунды
- Что делать на своей стороне, если это ваш сервер
Зачем вообще отзывают сертификат
Отзыв (revocation) — это действие удостоверяющего центра, которое говорит клиентам: «не доверяйте этому сертификату, хотя срок его действия ещё не истёк». Причины бывают разные:
- приватный ключ скомпрометирован — попал в репозиторий, лог, дамп памяти, был украден;
- сертификат выпущен по ошибке — не тому домену, не той организации, с нарушением политики CA;
- домен или сервис выведен из эксплуатации, а держать валидный сертификат на нём небезопасно;
- сама CA отзывает партию сертификатов из-за найденной у себя уязвимости в процессе выпуска.
Важно отличать отзыв от истечения срока действия. Истечение — это дата, зашитая в сам сертификат, её проверяет любой клиент локально, без обращения куда-либо. Отзыв — это внешнее событие, о котором клиент должен узнать отдельно, потому что сам сертификат при этом не меняется ни на бит: подпись CA на нём остаётся математически корректной, срок действия — не истёкшим. Единственный способ понять, что сертификату больше нельзя доверять — спросить у кого-то, кто знает о решении CA. Отсюда и берутся два конкурирующих механизма.
CRL: список, который нужно скачать целиком
CRL (Certificate Revocation List) — это подписанный CA файл со списком серийных номеров всех отозванных им сертификатов. Адрес, откуда его брать, обычно зашит в сам сертификат — в расширении CRL Distribution Points. Посмотреть его можно так:
openssl x509 -in cert.pem -noout -text | grep -A4 "CRL Distribution"
У CRL есть два поля, которые определяют его актуальность: thisUpdate (когда список сформирован) и nextUpdate (когда ждать следующую версию). Клиент, который хочет проверить сертификат через CRL, должен скачать список целиком и поискать в нём нужный серийный номер. Отсюда сразу два источника задержки:
- CA публикует CRL не постоянно, а по расписанию — конкретный интервал определяет сама CA в своём CP/CPS (Certificate Policy / Certification Practice Statement), это её внутренняя политика, а не фиксированный стандарт для всех. Пока не наступил
nextUpdate, в обороте может быть версия списка, сформированная до момента отзыва. - Список нужно физически скачать и распарсить, а с ростом числа отозванных сертификатов у крупных CA файл CRL становится большим — это одна из причин, по которой современные браузеры массово отошли от прямого скачивания полных CRL на каждое рукопожатие и предпочитают OCSP или собственные компактные форматы (о них ниже).
CRL остаётся источником истины — именно на нём в конечном счёте основаны и OCSP-ответчики CA, и агрегированные списки браузеров. Но напрямую его на каждое соединение почти никто не тянет: слишком дорого по трафику и по времени.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверOCSP: спросить именно про этот сертификат
OCSP (Online Certificate Status Protocol) решает ту же задачу иначе: вместо скачивания всего списка клиент отправляет короткий запрос с идентификатором конкретного сертификата (хеш от issuer-данных и серийный номер) на OCSP-ответчик CA и получает подписанный ответ: good, revoked или unknown. Адрес ответчика тоже прописан в сертификате — в расширении Authority Information Access:
openssl x509 -in cert.pem -noout -ocsp_uri
Проверить статус вручную можно так (нужен сертификат издателя для формирования запроса):
openssl ocsp -issuer issuer.pem -cert cert.pem \
-url http://ocsp.example-ca.com -text -noverify
OCSP быстрее и легче CRL, но не мгновенный: сам ответчик работает с данными, которые обновляются у него с какой-то периодичностью, а не читает базу отзывов CA в реальном времени на каждый запрос. У ответа тоже есть thisUpdate/nextUpdate — окно, в течение которого этот конкретный ответ считается действительным. Плюс у классического OCSP есть побочный эффект: каждое обращение клиента к ответчику CA технически сообщает CA, какой сайт вы посещаете. Это одна из причин, по которой на сцену вышел OCSP stapling.
OCSP stapling: сервер приносит ответ заранее — и тоже кеширует его
При OCSP stapling запрос к CA делает не браузер клиента, а сам сервер — заранее, в фоне, не в момент рукопожатия с конкретным посетителем. Полученный подписанный OCSP-ответ сервер «пришивает» (staples) прямо к TLS-рукопожатию, и клиент видит статус сертификата без отдельного похода к CA. Это решает и проблему приватности, и часть проблемы производительности.
Но здесь тот же принцип, что и с CRL: сервер не запрашивает свежий OCSP-ответ на каждое рукопожатие с каждым посетителем — это было бы так же дорого, как раньше делал клиент. Вместо этого сервер (или обвязка вроде nginx с ssl_stapling, HAProxy, Caddy) кеширует полученный ответ и переиспользует его, пока не истечёт его собственный nextUpdate, обновляя заранее, обычно за какое-то время до истечения. Пример конфигурации в nginx:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
Если сертификат отозван в тот момент, когда у сервера на руках уже лежит закешированный «хороший» ответ — сервер продолжает staple-ить именно его, пока сам не решит обновиться. Он не знает, что сертификат только что отозвали, потому что не спрашивает CA об этом непрерывно. Есть расширение Must-Staple (в сертификате прописывается требование обязательного stapling), которое ужесточает поведение клиента при отсутствии свежего ответа, но оно не сокращает само окно кеширования на стороне сервера.
Мягкий провал: если проверку не удалось выполнить, доверяем по умолчанию
Даже если бы CRL и OCSP всегда были идеально свежими, остаётся третий источник задержки — то, как клиент ведёт себя, когда проверка отзыва вообще не удалась: сеть недоступна, ответчик OCSP не отвечает, таймаут, DNS не резолвится. Есть два подхода:
- Hard-fail — если статус узнать не удалось, соединение блокируется. Строго с точки зрения безопасности, но означает, что временная недоступность инфраструктуры CA превращает половину интернета в недоступную для пользователя.
- Soft-fail — если статус узнать не удалось, клиент продолжает считать сертификат действительным и просто устанавливает соединение.
Большинство массовых браузеров исторически выбрали soft-fail как поведение по умолчанию для обычной (не EV) проверки: разработчики открыто объясняли это тем, что OCSP-инфраструктура CA сама по себе не всегда стабильна, и жёсткая блокировка при любом сбое ответчика превратила бы редкие проблемы инфраструктуры CA в массовые отказы легитимных сайтов — то есть ударила бы по доступности сильнее, чем помогла бы безопасности. Это осознанный компромисс вендоров, а не недосмотр.
Отдельно стоит подход через собственные агрегированные списки: например, у Chrome есть механизм CRLSet — периодически обновляемый и раздаваемый самим браузером компактный список наиболее значимых отозванных сертификатов (в первую очередь промежуточных CA и случаев массовой компрометации), который проверяется локально, без сетевого запроса на каждое соединение. У Firefox — похожий механизм, OneCRL. Это быстро и не зависит от доступности OCSP-ответчика в моменте, но именно поэтому такие списки принципиально не покрывают все отозванные конечные (leaf) сертификаты — только отобранный по значимости срез, обновляемый браузером со своей периодичностью.
Сколько это реально занимает — часы, дни, а не секунды
Если сложить всё вместе, полная цепочка задержки от «вы нажали отозвать» до «браузер типичного посетителя перестанет доверять» состоит из нескольких независимых звеньев:
- время до следующей публикации CRL или обновления записи в базе, которую читает OCSP-ответчик CA;
- если используется stapling — время, пока сервер не обновит свой закешированный OCSP-ответ;
- поведение конкретного клиента при недоступности проверки — soft-fail продлевает эффективное окно доверия ещё дальше, вплоть до полного игнорирования проверки в сценариях, где сеть до CA недоступна;
- для клиентов, которые вообще не делают живую проверку отзыва (полагаются только на агрегированные списки вроде CRLSet/OneCRL) — до следующего обновления такого списка у конкретного пользователя.
Точных единых цифр здесь не существует — они не стандартизованы для всех CA и всех браузеров одинаково, а зависят от политики конкретного удостоверяющего центра (её можно найти в CP/CPS этого CA) и от версии конкретного клиента. Порядок величины на практике — не секунды и не минуты, а часы и дни, и именно это стоит держать в голове: отзыв сертификата — это не аварийный выключатель с мгновенным эффектом, а запуск процесса, который распространяется по инфраструктуре с задержкой. Если нужно узнать конкретные цифры для своего сертификата — их можно прочитать прямо в нём и в ответе OCSP-ответчика:
openssl ocsp -issuer issuer.pem -cert cert.pem \
-url $(openssl x509 -in cert.pem -noout -ocsp_uri) -text -noverify \
| grep -E "This Update|Next Update"
Разница между This Update и Next Update в конкретном ответе — это и есть окно, в течение которого именно этот закешированный статус будет считаться действительным теми, кто его переиспользует.
Что делать на своей стороне, если это ваш сервер
Раз отзыв не гарантирует мгновенного эффекта, разумно не рассчитывать на него как на единственную линию защиты при компрометации ключа, а закладывать задержку в план действий заранее:
- Держите пайплайн переиздания сертификата быстрым. Если сертификат работает через Let's Encrypt и ACME-клиент вроде certbot или acme.sh, выпуск нового сертификата на новую пару ключей и его раскатка должны занимать минуты, а не часы — это надёжнее, чем ждать, пока распространится отзыв старого.
- Мониторьте сертификаты активно, а не полагайтесь на то, что клиенты сами заметят проблему — в частности, стоит отслеживать не только срок действия, но и факт отзыва по прозрачности сертификатов (Certificate Transparency logs), если вы допускаете риск компрометации.
- При компрометации ключа считайте, что окно риска — это дни, а не минуты, и параллельно с отзывом меняйте всё, что могло быть скомпрометировано вместе с ключом: другие секреты на том же сервере, доступы, токены — отзыв сертификата сам по себе не закрывает скомпрометированный канал немедленно.
- Если инфраструктура позволяет — включайте OCSP stapling (пример конфигурации выше) не столько ради ускорения отзыва, сколько ради приватности посетителей и снижения нагрузки на внешний OCSP-ответчик при рукопожатиях.
- Не держите долгоживущие сертификаты там, где риск компрометации выше среднего. Автоматическое переиздание раз в 60–90 дней через ACME снижает пользу от долгого окна, которое даёт классический отзыв — сертификат и так скоро сменится сам по себе.
Если сервер, на котором крутится ACME-клиент и nginx или Caddy с автообновлением сертификатов, регулярно тормозит именно в момент, когда нужно быстро переиздать и раскатать сертификат — возможно, дело не в DNS-провайдере и не в CA, а в ресурсах самой машины. Для такого сценария подойдёт аренда сервера с предсказуемым откликом и без соседей, которые внезапно съедают CPU в момент вашего ACME-challenge.
Разобраться, что вообще происходит на TLS-рукопожатии до момента, когда OCSP-статус вообще запрашивается, помогает статья про TLS-рукопожатие и что происходит до первого байта. Если интересна практическая сторона автопродления через Let's Encrypt — есть отдельный разбор почему сертификат Let's Encrypt не обновляется автоматически и как настроить мониторинг сертификатов и доменов, чтобы не узнавать о проблемах постфактум. А для тех, кто менял цепочку сертификатов и словил неожиданный обрыв — пригодится история про удалённый промежуточный сертификат, из-за которого отвалилось приложение: она хорошо показывает, что клиенты по-разному собирают и проверяют цепочку доверия, и это тоже часть общей картины с отзывом.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем OCSP лучше CRL, если оба не мгновенные?
OCSP обычно легче по трафику (короткий запрос про один сертификат вместо скачивания всего списка) и быстрее актуализируется у большинства CA, но принципиальной разницы «мгновенно против отложенно» между ними нет — оба зависят от того, как часто источник данных обновляется и как долго кешируется ответ.
Можно ли заставить свой браузер работать в режиме hard-fail, чтобы не рисковать?
У части браузеров такая настройка была доступна через политики или флаги в разное время, но это нестандартное для обычного пользователя поведение, и включение hard-fail может приводить к недоступности легитимных сайтов при любом сбое OCSP-инфраструктуры CA — это осознанный компромисс, а не однозначно «более безопасный» режим без побочных эффектов.
Если я отозвал сертификат через Let's Encrypt, когда он перестанет работать у посетителей?
Единого точного срока нет — это зависит от того, использует ли конкретный клиент живую проверку OCSP/CRL вообще, кеширует ли её результат ваш собственный сервер (при stapling) и как ведёт себя браузер посетителя при недоступности проверки. Рассчитывать нужно на часы-дни, а не на мгновенный эффект, и параллельно с отзывом стоит как можно быстрее раскатать новый сертификат на новом ключе.
OCSP stapling защищает от утечки истории посещений — а что насчёт классического OCSP?
Без stapling каждый клиент сам обращается к OCSP-ответчику CA при посещении вашего сайта, и теоретически CA может видеть, кто и когда проверял статус какого сертификата. Stapling убирает этот прямой канал, потому что запрос к CA делает сервер, а не тысячи отдельных браузеров посетителей.
Есть ли способ проверить отзыв быстрее, чем ждут стандартные механизмы?
Прямой запрос к OCSP-ответчику CA через openssl ocsp (пример команды выше) покажет текущий статус, который знает сам ответчик, без промежуточного кеша на вашем сервере — это самый близкий к реальному времени способ, но он всё равно ограничен тем, как часто сам ответчик обновляет данные из базы CA.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →