Прямо сейчас в интернете наличествует некая проблема, и, насколько я могу судить, с течением времени она лишь становится серьёзнее: всё большее и большее число сайтов получают сертификаты (что необходимо для запуска HTTPS), но у нас нет способа защитить себя, если «что-то пойдет не так».
Сертификаты
В настоящее время тема сертификатов довольно актуальна, поскольку все больше и больше сайтов развертывают HTTPS. Помимо очевидных преимуществ HTTPS (связанных с безопасностью и конфиденциальностью), есть ещё несколько причин, по которым вам может захотеться перейти на безопасное соединение, которое я описываю в своей статье «Вы всё ещё думаете, что вам не нужен HTTPS?». Сертификаты (те, что часто называются «SSL-сертификатами» или «сертификатами HTTPS») всё более востребованы, и выдаются со скоростью, которую мы никогда не видели за всю историю интернета. Каждый день я запрашиваю в интернете страницы первого миллиона сайтов из топа Alexa, и анализирую для каждого различные аспекты безопасности, а затем, раз в 6 месяцев, публикую отчет. Вы можете посмотреть отчеты здесь, но главный результат, на котором нужно сосредоточиться здесь и сейчас — это всё более растущая распространенность HTTPS.
Мало того, что мы продолжаем внедрять HTTPS, но и сама скорость, с которой мы это делаем, увеличивается (прим. переводчика: очевидно, до точки насыщения). Выше вы можете видеть, как выглядел прогресс в последние годы, а Firefox Telemetry дает еще более наглядные цифры на графике процента страниц, загруженных по HTTPS. Процесс получения сертификата с течением времени становился все более и более простым, а сейчас, благодаря удивительному сервису Let’s Encrypt, получение их стало ещё и бесплатным.
Грубо говоря, мы отправляем в Центр сертификации (Certificate Authority, или CA) запрос на выпуск сертификата (Certificate Signing Request, или, короче, CSR), CA, со своей стороны, проверяет, действительно ли мы управляем доменым именем, для которого запросили сертификат (для этого нас просят создать в DNS-зоне домена определенного вида TXT-запись, либо разместить файл со трудноугадываемым именем и определенным содержимым по случайному пути на сайте, работающем на нашем домене). Как только эта проверка удастся, CA выпустит необходимый сертификат, и мы сможем использовать его при настройке HTTPS на веб-сервере.
Я даже сделал несколько руководств, чтобы помочь вам с получением и настройкой использования сертификатов (см. посты по поводу get started, smart renewal и dual certificates). Это все здорово, и что же тут плохого? Проблема в том, что не всё идет, как задумывалось, и новости для нас не самые приятные.
«Нас взломали»
Никто никогда не хочет услышать подобные слова, но печальная реальность заключается в том, что их всё же приходится слышать, и чаще, чем любой из нас хотел бы. Хакеры пробуют пробраться на наш сервер множеством уже известных (и новых) способов, и, когда они получают доступ к нашему серверу, они могут получить и секретную часть нашего сертификата, так называемый Private Key.
Как вы знаете, сертификат состоит из двух частей: секретной (private key) и публичной (public key), обе эти части должны размещаться на веб-сервере для того, чтобы настроить HTTPS. Публичная часть сертификата, который мы использовали для настройки HTTPS, являются общедоступной; наш веб-сервер отправляем её любому, кто подключается к нашему сайту, и браузер этого посетителя использует полученную от нас публичную часть нашего сертификата, чтобы зашифровать информацию, передаваемую от браузера на наш сервер — при этом расшифровать эту зашифрованную информацию можно только при помощи второй, секретной, части того же сертификата. Поскольку ни у кого, кроме нас, нет секретной части сертификата, то никто не сможет использовать наш сертификат. Но если злоумышленник получит доступ к секретной части сертификата, картина существенно изменится.
Если злоумышленнику удастся заполучить секретный ключ нашего сертификата, он сможет изображать нас (точнее, наш сервер), т.е. показывать всем, что он — это мы. Ещё раз: в Интернете окажется кто-то, кто может доказать, что он — это вы, при этом не будучи вами. Это действительно проблема, и, прежде чем вы решите, что «со мной такого никогда не случится», вспомните пресловутый [Heartbleed] (http://heartbleed.com/)! В тот раз крошечная ошибка в коде библиотеки OpenSSL позволяла злоумышленнику украсть закрытый ключ сертификата с веб-сервера даже при отсутствии ошибок в конфигурации веб-сервера. Кроме того, секретные ключи могут оказаться известны злоумышленникам случайно или по неосторожности — и вероятность такого события также следует учитывать. Примите как данность, что наш закрытый ключ может тем или иным образом стать известным кому-то плохому, и, когда это произойдет, нам понадобится механизм, как не дать злоумышленнику использовать наш сертификат. Другими словами, нам нужно будет отозвать сертификат.
Аннулирование (revocation) сертификата
Столкнувшись с утечкой частей сертификата, мы, как это называется, аннулируем, или отзываем (помечаем как отозванный) наш сертификат, чтобы злоумышленник не смог его использовать. Как только сертификат окажется помечен как отозванный, браузер поймет, что ему нельзя доверять, даже если он не истёк по времени. Если владелец сертификата запросил аннулирование сертификата для своего домена, ни один клиент, очевидно, не должен принимать этот сертификат.
Как только мы узнаём, что у нас случилась утечка данных сертификата, мы связываемся с CA, выпустивший сертификат, и просим их, чтобы они произвели отзыв сертификата. Нам потребуется подтвердить право владения соответствующим сертификатом, и, как только мы это сделаем, центр сертификации пометит у себя в системе сертификат как отозванный. Теперь сертификат отозван, и нам нужно как-то сообщить об этом факте любому веб-клиенту в мире. Пока браузер не узнает об отзыве, он продолжит принимать сертификат, как если бы никакого аннулирования не произошло. На сегодня существуют два механизма, которые мы можем использовать, чтобы сделать эту информацию доступной всем:
- Списки отозванных сертификатов (Certificate Revocation List, или CRL)
- Протокол состояния сетевого сертификата (Online Certificate Status Protocol, или OCSP).
Certificate Revocation List, более известные как CRL
CRL в буквальном смысле представляет собой список всех сертификатов, которые конкретный СА (выпустивший их ранее) пометил как отозванные. Клиент может связаться со специальным сервером CRL этого CA, и загрузить их CRL. Вооруженный копией списка, браузер сможет проверить, указан ли сертификат, который ему предоставили, в этом списке. Если сертификат в списке, браузер точно знает, что сертификату нельзя доверять, а следует вывести ошибку и прекратить соединение. Если же сертификата нет в списке, то все в порядке, и браузер может продолжить соединение.
Проблема с CRL состоит в том, что они содержат много отозванных сертификатов от конкретного CA. Очень много. Да, эти списки разбиваются по промежуточным сертификатам, которые есть у CA, плюс CA может разбивать списки на более мелкие фрагменты по другим принципам, но суть, которую я хочу подчеркнуть, остается неизменной: CRL, как правило, имеют весьма приличный размер, что мешает загрузить такой список быстро. Более того, что, если у клиента нет свежей копии CRL данного CA, он должен как-то загрузить её во время первоначального подключения к сайту, что может заметно замедлить процесс первого соединения. Другими словами, не всё так просто, поэтому давайте познакомимся со вторым вариантом, а именно с OCSP.
Online Certificate Status Protocol, или OCSP
OCSP обеспечивает более красивое решение вопрос проверки статуса сертификата, плюс имеет другие преимущества по сравнению с подходом CRL. С помощью OCSP мы запрашиваем у CA статус отдельного конкретного сертификата. Всё, что CA должен в ответ сделать — это дать простой и короткий ответ, не отозван ли этот сертификат (буквально, сообщить, сертификат «валиден» или «отозван»; такой ответ по размеру куда меньший, чем передача всего CRL). Прекрасно!
Действительно, OCSP даёт значительное преимущество в скорости по сравнению с получением объемного CRL, но за всё приходится платить (вы, наверное, ненавидите эту фразу?). В данном случае платой выступает ваша конфиденциальность.
Если вдуматься, то запрос OCSP — т.е. запрос о статусе одного конкретного сертификата — означает разглашение информации о том, на какой конкретно сайт вы заходите. Когда вы (ваш браузер) отправляете запрос OCSP, вы, по сути, спрашиваете CA:
Валиден ли сертификат для pornhub.com?
Не самый идеальный вариант, правда? Вы (возможно, даже не осознавая этого) сообщаете какой-то третьей стороне свою историю посещений, и всё это во имя HTTPS, который задумывался с целью обеспечить вам больше безопасности и конфиденциальности. Иронично, не так ли? Но подождите, это ещё не всё!
А если проверка не удалась?
Выше мы говорили про списки CRL и ответы OCSP, про два механизма, которые браузер может использовать для проверки статуса отзыва сертификата. Вместе они выглядят примерно так:
После получения сертификата от веб-сервера браузер подключится к одной из этих служб и выполняет необходимый запрос, чтобы, в конечном итоге, выяснить статус сертификата. Но что, если у вашего CA авария и их инфраструктура просто недоступна? Что, если картина будет выглядеть так:
У браузера есть только два варианта. Он может отказаться принять сертификат, потому что не может проверить статус его аннулирования, или может рискнуть и принять сертификат, даже не зная статуса аннулирования. Оба эти варианта имеют свои преимущества и недостатки. Если браузер откажется принять сертификат, то каждый раз, когда у вашего CA что-то не задалось, и его инфраструктура оказалась недоступной, ваши сайты тоже становятся недоступными. Если же браузер продолжит работу и примет сертификат, он рискует использовать сертификат, который мог быть украден, и подвергнуть пользователя соответствующим рискам.
На сегодня мы имеем такое поведение браузера: он пробует произвести проверку аннулирования сертификата. Если ответ не был получен, либо (что вернее) не был получен в течение достаточно короткого периода времени, браузер просто «забудет» про необходимость проверки. Хуже того, Chrome вообще не проверяет аннулирование. Да, вы правильно прочитали: Chrome даже не пытается проверить статус отзыва сертификатов, с которыми он сталкивается. Однако, если вдуматься, в этом есть смысл.
Да, браузер теперь попытается выполнить проверку отзыва, но в конечном итоге откажется от проверки, если она занимает слишком много времени или, если, как кажется, сервера CA недоступны.
Стоп, что это была за последняя фраза? Проверка аннулирования отменяется, если «как кажется, сервера CA недоступны». Интересно, может ли злоумышленник смоделировать такую ситуацию?
Если у нас есть (некий воображаемый) злоумышленник, способный и желающий выполнить атаку MiTM, всё, что ему нужно, просто заблокировать запрос статуса аннулирования, т.е. сделать так, чтобы для клиента сервера CA были недоступны. После этого браузер провалит проверку и продолжит успешно использовать, возможно, уже отозванный сертификат. Неприятно: вы можете годами заходить на сайт, пока он не взломан, и на каждом заходе ваш браузер будет производить все проверки аннулирования сертификата, а в тот раз, когда вы зайдёте на этот же сайт, но подвергшийся взлому, проверка аннулирования не среагирует, поскольку взломщик сделает так, что проверка не даст никакого ответа — и браузер примет такой итог за разрешение зайти на сайт. Годы затрат ресурсов клиента на проверки — а в нужный момент проверка просто не произойдет и не убережет нас!
Решения вопроса
К сожалению, на сегодня нет надежного способа решить эту проблему, и аннулирование не работает. Однако, кое-что все же может помочь нам в желании быть уверенными, что сертификат для нашего домена не будет использован для неблаговидных целей.
Собственные, проприетарные механизмы
Если сервер оказался взломан, и злоумышленник завладел закрытым ключом, он может выдать сайт на своем сервере за исходный сайт, и причинить немало вреда. Это не хорошо, но может быть и хуже. Представьте, что случится, если окажется скомпрометирован сам CA, и злоумышленник получит доступ к закрытому ключу для промежуточного сертификата CA? Это будет катастрофа совсем другого масштаба, потому что злоумышленник сможет выдать себя за любой другой сайт, подписав свои собственные сертификаты для любого домена. Вместо того, чтобы проводить онлайн-проверки для отзыва промежуточных сертификатов, Chrome и Firefox имеют свои собственные механизмы, которые работают одинаково.
Chrome называет их CRLsets, а Firefox — OneCRL. Обе компании формируют собственные списки отозванных сертификатов, выбирая для них данные из доступных списков отзыва сертификатов. Так что, ценные сертификаты, такие, как промежуточные сертификаты CA, оказываются прикрытыми, но как насчет ваших и моих?
OCSP Must-Staple
Чтобы объяснить, что такое OCSP Must-Staple, нам сначала понадобится краткая справка о идее под названием OCSP Stapling. Я не буду вдаваться в подробности (вы можете прочесть подробнее в моем блоге: OCSP Stapling. Вкратце, OCSP Stapling позволяет браузеру выполнить проверку OCSP, получив ответ OCSP вместе с сертификатом. Это называется Stapling (буквально — подшивка), потому что смысл идеи в том, что сервер запрашивает OCSP ответ от CA, затем, словно бы степлером, «подшивает» полученный ответ OCSP к сертификату на домен сайта, и отправляет клиенту их оба вместе.
На первый взгляд это кажется немного странным, потому что сервер почти «самосертифицирует» свой собственный сертификат как не отозванный, но, по сути, всё разумно. Ответ OCSP действителен только в течение короткого периода времени, и он подписан со стороны CA так же, как и сам сертификат. Таким образом, если браузер может проверить, что сертификат был получен от CA, он может проверить и что ответ OCSP также пришел от CA. Это решает проблему конфиденциальности с OCSP, а также избавляет клиента от необходимости выполнять этот внешний запрос. Победа!
Но на самом деле все не так радужно. OCSP Stapling как идея — великолепна, и мы все должны использовать его на наших сайтах, но можем ли быть уверены, что злоумышленник включит OCSP Stapling у себя на сервере? Я так не думаю. Нам нужен способ заставить сервер использовать OCSP Staple, этой цели и служит вещь под названием OCSP Must-Staple. Это всего лишь флаг, который устанавливается CA в сертификате при его выдаче, и этот флаг указывает браузеру, что сертификат обязательно будет передан с сервера в комплекте с ответом OCSP, в противном случае должен быть отклонен.
Теперь, когда у нас есть сертификат с установленным соответствующим флагом, мы, как хост, должны убедиться, что мы правильно настроили OCSP Staple, иначе ни один браузер не примет наш сертификат. В случае компрометации и получения злоумышленником нашего ключа, для его использования ему также придется настроить работу OCSP Staple. Если злоумышленник не настроит поддержку OCSP Staple, браузер отклонит сертификат (потому что флаг OCSP Must-Staple в сертификате предпишет это сделать), а если всё же настроит OCSP Staple, то в ответе OCSP будет указано, что сертификат отозван, и браузер отклонит его. Класс!
OCSP Expect-Staple
Хотя Must-Staple звучит как отличное решение проблемы отзыва, это еще не совсем так. Одна из самых больших проблем, с которыми я сталкиваюсь, заключается в том, что я, как оператор сайта, на самом деле не знаю, насколько надежно я использую OCSP и всех ли клиентов устраивают «сшитые», благодаря OCSP Staple, ответы моего веб-сервера. Без включенного OCSP Must-Staple это не было бы проблемой, но если мы включим OCSP Must-Staple, а затем не будем правильно или надежно использовать OCSP Staple, наш сайт перестанет открываться. Чтобы попытаться получить некоторую обратную связь о том, как мы работаем с точки зрения сшивания OCSP, мы можем включить функцию под названием OCSP Expect-Staple.
Я писал об этом раньше, и вы можете получить все подробности в моем блоге в посте OCSP Expect-Staple, вкратце это выглядит так: вы запрашиваете добавление в список HSTS preload записи, заставляющей браузер отправлять вам отчёт, если ему почему-то не понравится настройка OCSP Staple на вашем сервере. Вы можете собирать отчеты самостоятельно, или использовать мой сервис report-uri.io, главное, что вы сможете точно узнавать, когда столкнетесь с проблемами, если вы включили OCSP Must-Staple. Поскольку добавление в список предварительной загрузки HSTS не так просто, как хотелось бы, я подготовил спецификацию для определения нового заголовка безопасности под названием Expect-Staple для предоставления той же функциональности, но с меньшими затратами усилий. Идея заключается в том, что теперь вы можете установить этот заголовок и включить отчеты, чтобы получить обратную связь, в которой мы отчаянно нуждаемся, прежде чем включать Must-Staple. Включение заголовка будет простым, как и все другие заголовки безопасности:
Expect-Staple: max-age=31536000; report-uri="https://scotthelme.report-uri.io/r/d/staple«; includeSubDomains; preload
Мошеннические сертификаты
Еще одна вещь, которую мы должны учитывать, когда говорим об отзывах сертификатов — это так называемые мошеннические сертификаты. Если кому-то удастся взломать CA, или иным образом получить сертификат на доменное имя, которым не владеет, как мы об этом узнаем? Если бы я прямо сейчас нашёл дыру в защите CA, и получил бы сертификат на домен вашего сайта, не сказав вам об этом, вы бы никогда не узнали об этом, пока новость об этом не разошлась бы достаточно широко. Возможно, у вас в организации есть нечестные сотрудники, которые в обход всех ваших внутренних процедур получили сертификат на домен организации (у другого CA, нежели тот, у кого получала сертификат ваша компания), и используют его для своих целей. Нам нужен механизм обеспечения полной прозрачность процесса выдачи сертификатов, и он называется Certificate Transparency.
Certificate Transparency
CT — это требование, чтобы все сертификаты, которым браузер должен доверять, были бы зарегистрированы в открыто доступном журнале. Вы можете прочитать про CT поподробнее, но в общем случае CA регистрирует все сертификаты, которые он выдает, в журнале CT.
Эти журналы являются общедоступными, и каждый желающий, например, может поискать в них имя своего домена, поэтому конечный смысл CT состоит в том, что, если каким-то из CA для вашего сайта будет выдан сертификат, вы узнаете об этом. Например, здесь вы можете видеть все сертификаты, выданные для моего домена, или использовать для того же сервис CertSpotter от sslmate. Я использую инструмент Facebook Certificate Transparency Monitoring, который умеет отправлять по электронной почте уведомление каждый раз, когда происходит выдача нового сертификата для конкретного домена. CT — фантастически хорошая идея, но (как обычно) есть момент, на который следует обратить внимание: CT — это только первый шаг. Знание списка выдаваемых сертификатов — это здорово, но у нас сохраняются все вышеупомянутые проблемы с отзывом их. Тем не менее, если мы можем решить только одну проблему за раз, то лучше начинать с CT, поскольку даже существование лучших в мире механизмов отзыва не имеет смысла, если мы не знаем о сертификатах, которые нам необходимо отозвать.
Certificate Authority Authorization (CAA)
Остановить выдачу сертификата гораздо проще, чем пытаться отозвать его, и это именно то, зачем придумана Certificate Authority Authorization. Если кратко, то идея заключается в том, что мы можем разрешить выдавать нам сертификаты только определенным CA. Это очень просто, достаточно создать одну запись DNS:
scotthelme.co.uk. IN CAA 0 issue "letsencrypt.org"
Хотя CAA не является особенно мощным механизмом, чтобы помочь во всех возможных сценариях ошибочной выдачи сертификатов, кое в чём он точно полезен, так что стоит выразить свои предпочтения в смысле выбора CA, и создать запись CAA для своего домена.
Несколько слов напоследок
В настоящее время существует реальная проблема: мы не можем отозвать сертификат, даже если кто-то тем или иным образом получит его закрытый ключ. Только представьте, чем это закончится в следующий раз, когда появится очередной Heartbleed! Чтобы попытаться ограничить влияние утечки, вы можете сократить срок действия сертификатов, которые вы получаете. Вместо трех лет брать его на один год или даже меньше. Let’s Encrypt выдает сертификаты вообще на срок в 90 дней! С уменьшением срока валидности вашего сертификата у вас будет меньше проблем, даже если случится утечка сертификата, потому что у злоумышленника останется меньше времени на злоупотребление сертификатом до окончания срока его действия. Помимо этого, мы пока мало что можем сделать.
Итак, у нас остается исходный вопрос: должны ли мы исправить механизмы аннулирования сертификатов, и как? Но, кажется, это та еще история!
Оригинальный текст датирован 03.06.2017, однако, к сожалению, материал не утратил актуальность. Тем не менее, я изменил часть текста так, чтобы изложенное отражало текущее положение дел — однако выдавать статью за свою всё же не считаю возможным.
Комментарии (8)
vibornoff
20.11.2019 16:47Проблема отзыва сертификата — фундаментальна и не имеет решения в рамках текущей системы PKI.
Если подумать, результатом выполнения проверок отзыва является некий эфемерный сертификат, срок действия которого равен межпроверочному интервалу. Т.е. по сути всё так или иначе сводится к уменьшению срока действия сертификатов.
Даёшь сертификаты с валидностью сутки! Или даже час!11speshuric
21.11.2019 01:04There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil KarltonИ тут как раз первая :)
darkdaskin
20.11.2019 17:18Поддомен
revoked.scotthelme.co.uk
возвращает валидный сертификат на*.scotthelme.co.uk
и перенаправляет на основной домен. Видимо, эта демонстрация более недоступна. Стоит убрать соответствующий абзац из статьи.achekalin Автор
20.11.2019 22:48Удалил этот абзац. Действительно, автор явно воспользовался возможностью получить у LE wildcard-сертификат, и не стал заморачиваться с поддержкой старой демки.
sotnikdv
21.11.2019 08:10+1сертификат состоит из двух частей: секретной (private key) и публичной (public key),… Публичная часть сертификата
В этом месте я читать и бросил. Покажите мне секретную часть X.509 сертификата плз.
Смешались в кучу ключи и сертификаты. Если с самого начала у автора такая каша в голове, то нет смысла продираться через остальные ошибки и выводы, на основе неверного понимания.
ildarz
https://habr.com/en/post/332730/