ADG Оставить заявку
Блог Информационная безопасность 4 мин чтения

SSL-сертификаты у клиента: 14 штук, три сервера, часть просрочена

После Heartbleed и POODLE взялись за инвентаризацию SSL у одного клиента - нашли 14 сертификатов с разными сроками, часть уже истекла. Строим реестр и мониторинг через Zabbix.

Контекст момента

После серии SSL-инцидентов 2014 года (Heartbleed, POODLE) инвентаризация сертификатов у одного из клиентов выявила 14 SSL-сертификатов на разных серверах с хаотичными сроками - часть уже просрочены

После POODLE в октябре мы прошлись по конфигурациям TLS у всех managed-клиентов. Протоколы поправили, cipher suites подтянули - в общем, конфиги стали приличнее. Но в процессе у одного клиента всплыл отдельный вопрос, который раньше не стоял ребром: а сколько у них вообще SSL-сертификатов и когда они истекают?

Вопрос казался простым. Оказался нет.

Что нашли

Инфраструктура клиента - три физических сервера и несколько виртуальных машин. Внешне выглядело как «пара сайтов и почта». На деле оказалось, что сертификаты есть:

  • На nginx-серверах - основной домен, поддомен для личного кабинета, поддомен API, тестовая копия (да, с отдельным сертом).
  • На почтовом сервере - SMTP, IMAP, веб-интерфейс Roundcube - все три разные, потому что в разное время ставили разные люди.
  • На внутренних сервисах - VPN-шлюз, внутренняя вики, мониторинг - здесь вперемешку самоподписанные и настоящие.
  • Где-то ещё - резервный сервер, который давно не трогали, там nginx тоже запущен и тоже с сертификатом.

Итого насчитали 14 сертификатов. Это не потому что клиент делал что-то странное - просто инфраструктура росла по одному сервису, каждый ставил тот, кто его настраивал, и никто ни разу не собирал всё в одно место.

Дальше хуже: три сертификата уже истекли. Не «скоро истекут» - уже. Один - на тестовом поддомене, два - на внутренних сервисах. Браузеры ругались, но никто особо не смотрел, потому что «это же внутреннее».

Почему это проблема

Истёкший сертификат на внутреннем сервисе - это не просто раздражающий браузерный варнинг. Это:

  • Потеря индикатора. Когда сертификаты всегда с варнингами, пользователи начинают кликать «продолжить» на автомате. Включая на тех ресурсах, где сертификат настоящий, но скомпрометированный.
  • Зазор в мониторинге. Если никто не следит за сроками, сертификат на боевом сервисе тоже может протухнуть - просто заметят позже.
  • Ручная работа в неудобный момент. Обычно об истечении узнают, когда пользователь пишет «у вас сайт сломался». Обновлять сертификат в таком режиме - не лучшая ситуация.

Как сделали реестр

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

  • домен / сервис
  • сервер (hostname)
  • порт
  • кто выдал (CA или self-signed)
  • дата истечения
  • ответственный (кто продлевает)
  • последнее обновление

14 строк занял час. Сразу стало видно, что три сертификата от одного CA истекают в течение двух недель, и их можно обновить одним заходом, а не тремя отдельными итерациями.

Мониторинг через Zabbix external check

Таблица - это хорошо, но полагаться на то, что кто-то будет её открывать и сверяться с датами вручную, наивно. Настроили проверку через Zabbix.

Zabbix поддерживает external checks - это когда вместо встроенного item type используется внешний скрипт, результат которого Zabbix читает как метрику. Скрипт простой: openssl s_client + openssl x509 -noout -enddate, считаем разницу с текущей датой в сутках.

#!/bin/bash
HOST=$1
PORT=${2:-443}
DAYS=$(echo | openssl s_client -connect "${HOST}:${PORT}" -servername "${HOST}" 2>/dev/null \
  | openssl x509 -noout -enddate 2>/dev/null \
  | sed 's/notAfter=//' \
  | xargs -I{} date -d "{}" +%s \
  | xargs -I{} bash -c 'echo $(( ($1 - $(date +%s)) / 86400 ))' _ {})
echo ${DAYS:-0}

Кладём в /etc/zabbix/externalscripts/ssl_cert_days.sh, в Zabbix создаём items типа External check с ключом ssl_cert_days.sh[{HOST.NAME},443]. Триггеры: warn при меньше 30 дней, critical при меньше 14.

Для внутренних сервисов, которые слушают на нестандартных портах - тот же скрипт, другой параметр.

Одно ограничение: скрипт не умеет проверять самоподписанные сертификаты с нестандартным CA - openssl s_client отказывается без явного указания -CAfile. Для самоподписанных пришлось добавить флаг -verify_return_error 0 и отдельный путь. Немного грязно, но работает.

Что в итоге

Три просроченных сертификата обновили. На два внутренних поставили самоподписанные с корректной датой (три года), на тестовый поддомен - заодно снесли, он был не нужен. Итого 13 живых сертификатов, все в реестре, все под мониторингом.

Обидно, что такого реестра не было с самого начала - это ведь не сложно. Просто никто не думал об этом как о чём-то, требующем учёта, пока не начали копать настройки после серии инцидентов этого года. Heartbleed в апреле заставил обновить OpenSSL, POODLE в октябре - выкинуть SSLv3, а инвентаризация в декабре показала, что у клиента просрочена часть сертификатов, о которых все забыли.

Теперь хотя бы будет алерт за месяц до того, как что-то протухнет.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.