Мониторинг сертификатов на ISP

2023.08.18
Рассмотрим проблемы возникающие на сервере ISP Manager из-за высокого уровня энтропии, способы мониторинга и предотвращения инцидентов

На работе досталась задача по решению проблем и мониторингу сертификатов на ISP Manager.

Внесем немного ясности. Когда речь идет о десятках сайтов, имхо ISP избыточен, но когда их 1000 и над проектом работают люди с разной квалификацией, то веб-интерфейс будет крайне удобен.

Наша компания предоставляет готовые шаблоны сайтов интегрированные с другим нашим продуктом. С нашей стороны полный пакет обслуживания: доступность, стабильность и безопасность. Все технические вопросы решаем мы, никаких cloudflare, мы и без них хорошо справляемся (другими сервисами). Клиентам остается только припарковать к нам домен и лить трафик, дальше работаем мы.

Проблемы с сертификатами

На дворе 2023 год, https уже мейнстрим, поэтому без сертификатов никак. Юзаем let's encrypt (еще бы, ведь обслуживаем тысячи доменов).

Оказалось, что из-за большого количества доменов и клиентов образовался большой уровень энтропии.

Кто-то скрыл свой домен за обратным прокси типа cloudflare или в dns полный бардак. Кто-то уже давно от нас ушел, а где-то просто домены уже свободны по разным причинам. Но сайты на ISP до сих пор активны и есть просроченные сертификаты.

Мне удалось выяснить несколько видов проблем:

nginx SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch

Рассмотрим каждую проблему.

Владение доменами

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

Сначал для этого дела на коленке был сделан php скрипт, но так как это однопоток и приходится долго ждать - было решено переписать на golang. Вот репозиторий.

key values mismatch

nginx SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch

Здесь мы наблюдаем какой-то фантомный баг, который возникает случайно и очень редко, каких-либо закономерностей выявить не удалось. Вот обсуждение на форуме let's encrypt.

Причин этой ошибки 2 (интересная статья):

Однако, при перезапуске процесса получения сертификата все проходит успешно.

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

Лимиты

В пятницу ТП ISP решили нам помочь и перевыпустить все сертификаты ... а у нас там тысячи доменов среди которых чуть меньше половины невалидны.

В понедельник начали сыпаться жалобы от клиентов: мы уперлись в лимиты и больше не могли выпускать новые сертификаты, а новые сайты продолжали регистрироваться на нашем ISP.

Стоит отдельно поговорить про лимиты, так как не понятно о чем вообще идет речь?

Читая форумы и разбирая acme спецификацию я пришел к выводу что процесс выпуска сертификата для домена включает в себя авторизацию домена на acme сервере. Эта авторизация прекращается после выпуска сертификата или посредством отзыва авторизации через acme клиент.

Что происходило в нашем случае:

Как правило на одном web-сервере, который взаимодействует с let's encrypt посредством того же Certbot, используется один аккаунт на acme сервере, а он используется в любом случае.

Еще раз читаем доку по ограничениям от let's encrypt и видим:

Для одного аккаунта допускается не более 300 запросов на авторизацию, ожидающих ответа.

У нас накопилось более 300 процедур выпуска сертификата и мы начали получать ответ от acme сервера: Error creating new order :: to many currently pending authorizations: 300

Из этого обсуждения удалось выяснить что авторизация для домена истекает через 7 дней при бездействии (pendingAuthorizationLifetimeDays).

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

Оказалось что в такой ситуации мы не одиноки, есть проекты на тему отмены авторизации доменов. Например acmecancel, LE_FIND_PENDING_AUTHZ и letsdebug-toolkit, а clear-authz вообще веб (ссылка на реп).

Но большая часть этих проектов работает по старому протоколу v01, а у нас уже v02.

Да и не имеет это смысла, потому что в логах у нас нет enpoint authz с нашими нужными доменами. Возможно потому что наш certbot версии 0.33.

Есть еще полезные статьи от ISP как они вели разработку плагина сертификатов вот и вот.

Собрав всю мощь знаний интернета за день изучения, у нас назрели 2 пути решения проблемы:

Перечитал начало 7.4 и раздел 7.4.1 спецификации acme, план по самостоятельному закрытию авторизаций может не прокатить, надо тестить. А последствия второго неизвестны, хотя на формуах по ссылкам выше есть посты с подобными рекомендациями.

Вероятность выхода из лимитов увеличивается с каждым днем и на третий день мы вышли из лимитов.

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

Мониторинг

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

Первым делом я обратился к поиску встроенных в ISP решений по мониторингу. Их нет, ТП подтверждает. Значит нужно выкручиваться самим.

Я и есть тот самый профильный специалист, но мне хотелось использовать готовые решения.

Оказывается у самого ISP есть БД на sqlite расположенная по пути /usr/local/mgr5/etc/ispmgr.db.

Немного пошарив нашлись интересные таблицы:

На основании решаемых проблем и имеющихся для мониторинга данных составляем следующие метрики для мониторинга.

Домены в процессе получения

Как правило у нас единицы или десятки доменов одновременно получают сертификат, но если это массовое явление то это предвестник проблемы. Поэтому настраиваем звонок на значение меньше лимитов (>=100) чтобы вовремя вмешаться:

SELECT COUNT(*)
FROM letsencrypt_ssl
WHERE processing = 'on'

Домены, которые не смогли получить сертификат

Как мы уже знаем ISP не отменяет авторизацию домена на acme сервере, значит нам нужно следить за количеством доменов, которые не смогли получить сертификат. Не дожидаемся значения 300 и заранее звоним (>=50).

SELECT COUNT(*)
FROM letsencrypt_ssl
WHERE letsencrypt_ssl.failed = 'on'

Домены с проблемами получения сертификата

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

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

SELECT COUNT(*)
FROM (
    SELECT certname, COUNT(certname) as c
    FROM letsencrypt_log
    WHERE status = 'failed' AND date >= DATETIME('now', '-4 hour')
    GROUP BY certname
)
WHERE c > 1

Домены, у которых через 7 дней истечет сертификат

Certbot заранее обновляет сертификаты, но может произойти сбой обновления.

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

SELECT COUNT(*)
FROM letsencrypt_ssl
WHERE processing = 'off'
    AND failed == 'off'
    AND ((unixepoch('now') - unixepoch(time_started)) / 60 / 60 / 24) >= (90 - 7)

У кого sqlite ниже 3.38 вместо unixepoch можно использовать strftime.

Домены, у которых не настроен редирект или нет сертификата

Весь http трафик должен идти через https. Звонков не ставим, пока смотрим графики самостоятельно, по ходу накопления данных принимаем решение.

Не настроен редирект с http на https:

SELECT COUNT(*)
FROM webdomain
WHERE redirect_http = 'off' AND active = 'on'

Домены без сертификатов:

SELECT *
FROM webdomain
WHERE active = 'on' AND secure == 'off'

Предупреждение инцидентов

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

В телеграм канале DevOps от первого лица можно оставить комментарий или почитать интересные истории из практики DevOps