Обновление тестовых сертификатов: невидимый фронт

Photo by wu yi on Unsplash

В этой статье я поделюсь опытом в решении проблемы, о которой многие читатели наверняка не слышали или не думали, что она бывает таких масштабов – речь пойдет о своевременном автоматическом обнаружении устаревающих цифровых сертификатов открытого ключа (X.509) в тестовом окружении.

Статья описывает суть проблемы, а также процессы поиска и реализации ее решения. Читатели, страждущие результатов здесь и сейчас, могут сразу перейти к разделу «Резюме».

Целевая аудитория статьи: разработчики, тестировщики, технологи и другие специалисты, занятые в проектах с большим числом защищенных интеграций.

Содержание

А в чем, собственно, проблема?

Представьте себе…


Команда разработки ПО. День выпуска версии. Первые лучи солнца застают этих людей уже за работой; день расписан по часам. Короткие, предельно точные фразы лишь изредка нарушают гармоничную симфонию непрерывных щелчков клавиатур и мышек. Идет финальное тестирование. 71-ый пункт check-листа дает старт проверке одной из важнейших функций тестируемого продукта. Тестировщик переходит в нужный раздел приложения и… О, Боже! Что это? «Сервис временно недоступен. Пожалуйста, повторите попытку позже»

─ Еще вчера вечером всё было в порядке!

─ Этот функционал не изменялся в последней версии. Как он мог сломаться!?

─ Не может быть! Только не сегодня! Релиз под угрозой!..

Прошел месяц; быть может, два или три. День «Х» повторился. А спустя время – снова… А затем опять… И опять…


Что это за история? Сценарий мистического триллера для IT-шников? Или новомодная страшилка для детей программистов?

Нет. Это обобщенное описание реальных случаев из жизни Отдела разработки, в котором довелось трудиться автору этих строк. А мистический сбой – не полтергейст, не порча и даже не вирус; это цифровые сертификаты, срок действия которых непредвиденно истек в самый неподходящий момент.

Такие сертификаты используются повсеместно в нашем продукте – универсальном интернет-банке для множества партнеров – для защиты информации в многочисленных интеграциях со сторонними сервисами, в том числе в тестовом окружении.

Въедливый читатель вправе задать вопрос: «А зачем в тестовом окружении все эти сложности с безопасностью? Ведь это песочница; здесь нечего и не от кого защищать!» Это верно, однако защита информации в нашем продукте – слишком важный и нетривиальный аспект, чтобы позволять себе игнорировать его в тестовом окружении и надеяться, что «на боевом, авось, заработает; тут же все стандартно». Закон Мерфи говорит об обратном. Именно поэтому мы вынуждены «играть в защиту»: получать специальные тестовые сертификаты, но применять их по-настоящему.

Поставщики сертификатов (подразделения, ответственные за те или иные экземпляры внешних сервисов) выпускают их со стандартными сроками действия; как правило, это один год. Поскольку моменты выпуска различных сертификатов никак не связаны между собой, даты их истечения также оказываются хаотичными. Таким образом, можно «прикинуть», что при среднем сроке действия сертификата в 1 год мы имеем следующее.

  • Общее число защищенных интеграций:

    $$ I \approx 12 $$

  • Доля доп. интеграций из автономных приложений Комплекса: $$ A \approx \frac{1}{6} $$

  • Доля доп. интеграций в альтернативных окружениях: $$ O \approx \frac{1}{8} $$

  • Усредненная частота истечения сертификатов (штук в месяц):
    $$ F \approx \frac {\left(I + A*I + O*I \right)}{I} \approx 1,29 $$

В чем проявляются эти результаты? В таких историях, как была приведена в начале статьи, а также во множестве похожих, пусть и менее трагичных.

Но если заменить «плач Ярославны» на сухую конкретику, то проблема с тестовыми сертификатами зиждется на следующих обстоятельствах:

:mag: Кликните по картинке для увеличения
🔍 Кликните по картинке для увеличения

С некоторой долей условности сюда же отнесен и коварный характер самой проблемы (пункт 6 диаграммы) – она случается, что называется, «редко, но метко»: могут пройти месяцы беспечной работы, а затем настать «час Х», когда какой-нибудь внезапно устаревший сертификат парализует часть работы команды на срок от нескольких часов до нескольких дней.

Что ж, самое время проститься с теми читателями, для кого проблема осталась неясной или надуманной; дальше им будет скучно. А с теми, кто, утирая скупую слезу сочувствия, все еще верит в happy end, мы двинемся дальше…

Примечание для буквоедов

Строго говоря, понятие «обновление сертификата» не совсем однозначно. В отличие от стандарта OpenPGP, стандарт X.509 не допускает изменения атрибутов сертификата после его создания, в том числе даты окончания действия. В связи с этим, в контексте X.509 под обновлением всегда подразумевается выпуск нового сертификата на замену старому. Однако в силу распространенности такой формулировки она не требует явной оговорки.

Как быть?

Итак, несколько «трагических» случаев с тестовыми сертификатами привели нас (как отдел разработки) к пониманию, что, какой бы надуманной она не казалась, проблема есть и ее нужно решать. Поправив очки на носу характерным жестом, обозначим к ней два подхода.

Первый гипотетически заключался в том, чтобы «научить» всех поставщиков сертификатов выпускать свои сертификаты с вечным (читай «долгим») сроком действия. По разным причинам, зависящим только от самих поставщиков, этот подход, увы, остался гипотетическим. Одна из таких причин заключается в том, что предоставляемые сертификаты только для нас являются сугубо тестовыми; по ним же к некоторым сервисам обращаются внешние партнеры (банки), и предоставлять им бессрочные сертификаты было бы опрометчиво. Быть может, эта статья поможет выявить и другие причины, а в идеале – устранить их!

Второй строился на том, что коль скоро мы не в силах обойтись вообще без обновления сертификатов, а само обновление не поддается единственному процессу автоматизации (а писать свой процесс под каждый сертификат дороговато), то давайте хотя бы автоматизируем заблаговременное оповещение об устаревающих сертификатах? Ведь соль проблемы не только и не столько в самом обновлении, сколько в том, чтобы своевременно им заняться. А поскольку сотрудникам отдела и так есть, что постоянно помнить и контролировать, не стоит грузить их еще одной «задачей по расписанию», ее нужно автоматизировать. А это уже интересно…

Решение первое, оптимистичное

Естественно, никому не хотелось впахиваться на долгие месяцы или даже дни ради такой задачи, как описанный выше второй подход. Поэтому в отделе был выбран «крайний», коим оказался автор этой статьи, и ему было поручено «сделать какую-нить напоминалку». Не утруждая себя просчетом результатов, «крайний» наваял в Excel небольшую табличку, в которую выписал названия основных (далеко не всех) сертификатов, даты их истечения, места применения и пару примечаний. Этот документ был прикреплен к специально заведенной в Outlook задаче с напоминанием. Дата напоминания была выставлена равной скорейшей из дат истечения сертификатов (с запасом), а сама задача была разослана всем заинтересованным лицам отдела. Вот оно, счастье! Теперь все, кто нужно, получат напоминание перед тем, как истечет первый сертификат. Кроме того, появилось единое место, где можно узнать о состоянии основных сертификатов. Разве это не чудо?..

Оказалось, нет, не чудо. И причин тому несколько.

  • Необходимо вручную указывать все отслеживаемые сертификаты.

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

  • Необходимо вручную регулярно обновлять данные в напоминании и в таблице.

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

  • Необходимо вручную импортировать напоминание в Outlook всем заинтересованным лицам.

    Сама идея «автоматичности» всего решения сходила на нет, когда выяснялось, что для корректной работы получатели напоминания должны были не забывать явно импортировать его себе в Outlook.

Не трудно заметить обилие слова «вручную» в этих доводах. Вывод один – этот вариант автоматизации все еще слишком сильно зависит от человеческого фактора, а, значит, слишком ненадёжен.

Решение второе, выстраданное

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

  1. Все сертификаты в любых хранилищах в рамках каждого тестового сервера должны обнаруживаться автоматически, включая те, что будут добавляться в будущем.

  2. Не должно быть никаких перечислений сертификатов и/или сроков напоминаний, которые нужно было бы регулярно актуализировать.

  3. Все, что должно требоваться от заинтересованных лиц для получения напоминаний – желание их получать.

Получилось весьма благородно, не правда ли? Осталось понять, как это всё осуществить…

Конечно же, первое, что хочется сделать – это найти готовое решение и просто применить его к нашей задаче. Из похожего имеется встроенный в Windows инструмент напоминаний о сертификатах, однако он следит не за всеми сертификатами на диске, а лишь за явно импортированными в хранилище Windows. Это нам не подходит, так как противоречит пунктам 1 и 2 приведенных выше требований (назовем их «Кодекс сертификатоведа»). И это не говоря уж о том, что тестовые серверы работают под управлением Solaris, а не Windows, и даже не имеют графической оболочки. Другие рассмотренные инструменты ориентированы на единый источник сертификатов, что также смывает их в канализацию еще до попытки применения.

Посему принимаем радикальное решение – сотворить свой собственный велосипед инструмент.

От идеи до модели

Не мудрствуя лукаво, давайте замуруем в фундамент нашего решения идею, которая бы вобрала в себя всё «наболевшее»:

Создать небольшое приложение1️⃣, умеющее находить2️⃣ любые3️⃣ сертификаты на заданном4️⃣ тестовом сервере, проверять5️⃣ их срок действия, а при обнаружении среди них проблемных6️⃣уведомлять7️⃣ об этом ответственных за обновление лиц. Сделать это приложение параметризованным8️⃣ и запускать как фоновую задачу по расписанию9️⃣.

Вот, собственно, и всё, делов-то?.. Осталось начать да закончить. Ну и, между делом, придумать, как осуществить обозначенные цифрами «хотелки». Сделаем это на картинке: ​​

:mag: Кликните по картинке для увеличения
🔍 Кликните по картинке для увеличения

Ну вот, «хотелки» уточнены, всё почти готово. Дальше будем действовать по плану, предложенному ребятами из «Южного Парка»:

  1. Уточняем хотелки к приложению.

  2. Профит!

Уточню лишь, что за вторым пунктом кроются несколько дней разработки, а за третьим – рабочая версия утилиты, названной CertificateWatcher.

Выхлоп

Ещё только появлявшаяся на свет утилитка уже во время отладки показала свой потенциал – будучи впервые запущенной на основном тестовом сервере, она нашла на нем несколько сотен (!) безнадежно устаревших сертификатов, применявшихся в задачах прошлых лет, а ныне погребенных в гробницах хранилищах в самых разных уголках сервера. К счастью, нами был предусмотрен параметр «Запас времени на напоминание после истечения сертификата», благодаря которому эти рудименты не будут лишать сна ответственных за обновление лиц и снижать их бдительность.

Виртуальная бутылка шампанского была разбита о не менее виртуальное судно утилиты где-то в конце июня уже минувшего 2014-го года, и она была отпущена в настоящее эксплуатационное плавание.

Как и планировалось, в Jenkins’е была заведена задачка, которая запускала CertificateWatcher дважды в месяц в рабочее время так, чтобы за пять-десять минут до утреннего митинга всем заинтересованным лицам на почту падал еще теплый отчет обо всех проблемных сертификатах.

За прошедшие с той поры полгода суровая участь истечения должна была постигнуть в общей сложности 6 различных сертификатов тестового окружения. Ответственные за их обновление люди своевременно получали «письма счастья» от утилиты и благодаря этому раз за разом предотвращали потенциальные аварии.

Отладочный (и потому нарочито показательный) пример такого письма приведен на следующей картинке.

:mag: Кликните по картинке для увеличения
🔍 Кликните по картинке для увеличения

В один прекрасный день этого полугодия чарующий аромат сероводорода все же повеял от одного из важнейших (какого же еще?) сертификатов (он истек). Это породило новую волну дискуссий о проблеме и в конечном итоге вылилось в доработку утилиты – с недавних пор она умеет не только сообщать о результатах анализа по электронной почте, но и создавать заявки в JIRA для каждого нового проблемного сертификата. Заявки наполняются подробными сведениями о сертификате, включая перечень мест его использования, и автоматически назначаются на указанного в настройках сотрудника отдела.

Не менее гипертрофированный пример, чем для письма выше:

:mag: Кликните по картинке для увеличения
🔍 Кликните по картинке для увеличения

Данная заявка была создана автоматически по результатам работы утилиты на тестовом сервере с отладочными настройками.

Точки дальнейшего роста

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

  • Поддержка других форматов сертификатов. Мы предусмотрели возможность обработки таких форматов, как cer, crt, pfx и пр., но еще не реализовали ее.

  • Поддержка распределенного сканирования. Мы предусмотрели возможность работы с несколькими тестовыми серверами, но еще не реализовали ее.

  • Поддержка назначения наблюдателей для заявок в JIRA. Это может быть полезным для улучшения контроля над их исполнением.

  • ____________________________ (вписать нужное)

Резюме

Ряд инцидентов, связанных с непредвиденным истечением тестовых сертификатов, заставил нас (Отдел разработки) задуматься об инструменте для предотвращения подобных случаев.

Первое решение, основанное на реестре сертификатов в Excel и напоминаниях в Outlook, не оправдало себя. Тогда была разработана специальная утилита CertificateWatcher, которая:

  • Срабатывает автоматически по заданному расписанию (через Jenkins);

  • Находит проблемные (близкие к истечению или недавно истекшие) сертификаты на тестовом сервере;

  • Формирует уникальный список проблемных сертификатов и рассылает его по электронной почте заинтересованным лицам (задаваемым через настройки);

  • Создает заявки в JIRA для каждого нового сертификата, снабжая их перечнем точек использования сертификата и назначая их на указанного в настройках сотрудника.

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

Таков на сегодняшний день опыт нашего Отдела в решении этой проблемы. Приходилось ли вам сталкиваться с подобным? Как бы стали решать эту проблему в вашем подразделении? Давайте делиться опытом – добро пожаловать в комментарии!

Утилита CertificateWatcher пока не выложена на GitHub. Если вы заинтересованы в её применении, сообщите мне об этом, пожалуйста.
Владимир Плизгá
Владимир Плизгá
Ведущий инженер

Любимая технология: здравый смысл