Серверы
  • Готовые серверы
  • Конфигуратор
  • Серверы с 1CPU
  • Серверы с 2CPU
  • 4 поколение AMD EPYC
  • Серверы с AMD Ryzen и Intel Core i9
  • Серверы для хранения данных
  • Cерверы с портом 10 Гбит/c
  • Премиальные серверы
  • Серверы с большим объемом RAM
  • GPU
  • Распродажа
  • VPS
  • VPS / VDS серверы
  • Хостинг с ispmanager
  • GPU
  • Выделенные серверы с GPU
  • Виртуальные серверы с GPU
  • GPU-серверы с Nvidia RTX 5090
  • GPU-серверы с Nvidia RTX 6000 PRO
  • GPU-серверы с AMD Radeon
  • Распродажа
    Маркетплейс
    Colocation
  • Размещение серверов в дата-центре в Москве
  • Обслуживание серверов в других ЦОД
  • Прокат
    Услуги
  • Аренда сетевого оборудования
  • Защита L3-L4 от DDoS атак
  • IPV4 и IPV6 адреса
  • Администрирование серверов
  • Уровни технической поддержки
  • Мониторинг сервера
  • BYOIP
  • USB диск
  • IP-KVM
  • Трафик
  • Коммутация серверов
  • AI-чат-бот Lite
  • AI-платформа
  • О нас
  • Работа в HOSTKEY
  • Панель управления серверами и API
  • Дата-центры
  • Сеть
  • Тест скорости
  • Специальные предложения
  • Отдел продаж
  • Для реселлеров
  • Гранты для специалистов по Data Science
  • Гранты для научных проектов и стартапов
  • Документация и Частые вопросы
  • Новости
  • Блог
  • Оплата
  • Документы
  • Сообщите о нарушении
  • Looking Glass
  • 18.09.2025

    Мониторинг SSL-сертификатов в oVirt Engine: как мы научились спать спокойно благодаря Go и Prometheus

    server one
    HOSTKEY

    Авторы статьи: Артем Зубков, Junior администратор отдела DevOps.

    В современных распределённых системах надёжность и безопасность инфраструктуры напрямую зависят от корректного функционирования криптографических компонентов, в частности — SSL/TLS-сертификатов. Одним из критически важных аспектов эксплуатации таких систем является своевременный мониторинг срока действия сертификатов, поскольку их просрочка может привести к нарушению работы сервисов, недоступности API, сбоям в аутентификации и даже компрометации безопасности соединений. В рамках экосистемы oVirt Engine, выступающего центральным узлом управления виртуальной инфраструктурой, особое значение имеют сертификаты, обеспечивающие защищённое взаимодействие между компонентами системы и конечными пользователями.

    Серверы для мониторинга
    Закажите сервер с предустановленным ПО для мониторинга: Grafana, Zabbix, Prometheus и другими.

    В данной статье мы рассмотрим практику реализации автоматизированного мониторинга срока действия двух ключевых сертификатов: apache.cer и websocket-proxy.cer, размещённых на каждом oVirt Engine в директории /etc/pki/ovirt-engine/certs/.

    Сертификат apache.cer используется веб-сервером Apache, который обслуживает веб-интерфейс и REST API oVirt Engine, обеспечивая шифрование и аутентификацию клиентских подключений. В свою очередь, websocket-proxy.cer применяется для защиты WebSocket-соединений, необходимых для передачи консольных сессий виртуальных машин через браузер. Несвоевременное обновление этих сертификатов может привести к недоступности управления виртуальными машинами и административного интерфейса, что делает их мониторинг приоритетной задачей.

    Для решения этой задачи мы разработали специализированный экспортер — cert_checker, размещаемый непосредственно на каждом oVirt Engine в каталоге /opt/cert_checker. Для тех, кто не знает, oVirt Engine — это центральный сервер управления, который контролирует все ноды виртуализации, общие дисковые ресурсы и виртуальные сети.

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

    Для корректной работы экспортера требуется наличие на хосте установленной версии Go (golang) не ниже той, которая использовалась при его компиляции, что гарантирует стабильность и совместимость исполняемого файла. Далее в статье будет подробно описана архитектура решения, процесс развёртывания, формат выдаваемых метрик и рекомендации по интеграции в инфраструктуру мониторинга.

    Создание сервиса

    Для работы экспортера так же необходимо создать сервис systemd. Для это идем в каталог /etc/systemd/system/ и создаем systemd-unit:

    Description=oVirt cert cheker service
    ConditionPathExists=/opt/cert_cheker
    After=network.target
    [Service]
    Type=simple
    WorkingDirectory=/opt/cert_cheker
    ExecStart=/usr/local/go/bin/go run main.go //указать путь установки go и способ выполнения main.go
    User=root
    ExecReload=/bin/kill -HUP $MAINPID
    ExecStop=/bin/kill $MAINPID
    KillSignal=SIGQUIT
    TimeoutStopSec=5
    Restart=on-failure
    RestartSec=10
    [Install]
    WantedBy=multi-user.target

    После чего сделать

    systemctl daemon-reload
    systemctl start cert_cheker.service

    и проверить статус работы сервиса

    systemctl status cert_cheker.service

    В случае успеха вывод статуса должен выглядеть примерно так:

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

    Для этого нужно ввести, например, команду

    netstat -na | grep 1337

    Если вывод имеет следующий вид.:

    Тогда необходимо открыть порт вручную, введя команду

    firewall-cmd --add-port 1337/tcp

    Проверяем результат:

    Если порт открыт, следует проверить, тянется ли метрика. Для этого нужно ввести новую команду

    curl http://localhost:1337/metrics

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

    Создание алерта Prometheus

    Первым делом создаем алерт. Все примеры мы будем показывать ссылаясь на наш gitlab и расположение Ansible плейбуков для развертывания инфраструктуры в нем. В случае Prometheus, его алерты можно найти по по пути/devops/ansible-playbooks/prometheus_playbook/ files/alerts.

    Выбираем раздел меню New fileи создаем файл в формате yml:

    Затем пишем алерт, где указываем имя самого алерта, нужный для мониторинга атрибут + значение, на которое будет срабатывать алерт, время обновления, тип алерта (в нашем примере warning), а также описание. Формат следующий:

    groups:
    - name: ovirt_engine_apache_cert_expiry
      rules:
        - alert: ovr_apache_cert_expiry
          expr: ovirt_engine_apache_cert_expiry < 14
          for: 45s
          labels:
            severity: warning
          annotations:
            summary: "Certificate for {{ $labels.engine }} will expire soon"
            description: "The certificate for {{ $labels.engine }} will expire in {{ $value }} days. Please renew it."
    - name: ovirt_engine_ws_proxy_cert_expiry
      rules:
        - alert: ovr_ws_proxy_cert_expiry
          expr: ovirt_engine_ws_proxy_cert_expiry < 14
          for: 45s
          labels:
            severity: warning
          annotations:
            summary: "Certificate for {{ $labels.engine }} will expire soon"
            description: "The certificate for {{ $labels.engine }} will expire in {{ $value }} days. Please renew it."

    Сохраняем и переходим в каталог /devops/ansible-playbooks/prometheus_playbook/group_vars. Нас интересует файл federation_lang.yaml. Открываем его через web IDE и в верхней части документа, рядом с остальными таргетами, ниже создаем свой:

    В таргете прописаны имя таргета, путь на каталог на HTTP, поднятом ранее на 1337 порту. Далее, после static_configs, прописываем целевые адреса за портом 1337. Затем, после labels, название сервиса и компонент virtualization.

    Так же необходимо в самом начале документа, после поля rule_files указать имя написанного алерта:

    После этого переходим к Jenkins задаче conf_prometheus.dslи запускаем обновление fideration_lang:

    После успешного обновления следует перейти по URL (http://<ip>:9090/) и проверить отработку таргета, введя имя искомого атрибута, например ovirt_engine_apache_cert_expiry. Если проблем не возникло, то вывод будет примерно таким:

    Вывод алерта на дэшборд Grafana

    Если предыдущие шаги выполнены успешно, алерт будет выведен на общий дэшборд. Необходимо перенести его на дэшборд oVirt. Делается это следующим образом:

    Заходим в настройки панели, выбрав пункт меню Edit:

    Вписываем название алерта в формате job!="cert_cheker". Обязательно после должна быть запятая. Если название вписывается в середине поля, то запятую ставим с обеих сторон:

    Далее идем в дэшборд Prometheus AlertManager - Ovirt checks:

    На дэшборде oVirt снова заходим в настройке панели:

    Жмем + Query :

    В появившемся поле вписываем имя алерта опять в формате job="cert_cheker".

    После чего нажимаем Save в верхней части страницы:

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

    Описание работы кода экспортера

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

    Также необходимы пакеты encoding/pem для декодирования PEM-закодированных данных, io для работы с вводом-выводом, log для логирования, net/http для работы с HTTP-запросами, os для работы с операционной системой и time для работы со временем.

    Еще необходимо импортировать пакеты из внешних библиотек:

    • github.com/prometheus/client_golang/prometheus для работы с Prometheus;
    • github.com/prometheus/client_golang/prometheus/promhttp для обработки HTTP-запросов Prometheus:
    package main
    import (
        "crypto/x509"
        "encoding/pem"
        "io"
        "log"
        "net/http"
        "os"
        "time"
        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promhttp"
    )

    Дальше определяются две метрики: apacheCertExpiry и wsProxyCertExpiry, которые представляют собой измерители (gauges) в Prometheus. Они используются для отслеживания количества дней до истечения срока действия сертификатов Apache и WebSocket Proxy соответственно:

    var (
        apacheCertExpiry = prometheus.NewGauge(prometheus.GaugeOpts{
            Name: "ovirt_engine_apache_cert_expiry",
            Help: "Number of days until the Apache certificate expires",
        })
        wsProxyCertExpiry = prometheus.NewGauge(prometheus.GaugeOpts{
            Name: "ovirt_engine_ws_proxy_cert_expiry",
            Help: "Number of days until the WebSocket Proxy certificate expires",
        })
    )

    В функции init() эти метрики регистрируются в Prometheus с помощью функции prometheus.MustRegister():

    func init() {
        prometheus.MustRegister(apacheCertExpiry)
        prometheus.MustRegister(wsProxyCertExpiry)
    }

    В функции main() запускается HTTP-сервер (в данном случае на порту 1337), который будет принимать метрики в каталог /metrics, в формате который поддерживает Prometheus:

    func main() {
        log.Println("Starting HTTP server on :1337")
        http.Handle("/metrics", promhttp.Handler())
        go func() {
            log.Fatal(http.ListenAndServe(":1337", nil))
        }()

    Далее в бесконечном цикле каждый час проверяется срок действия сертификатов Apache и WebSocket Proxy с помощью функции checkCertExpiry(). Эта функция принимает путь к файлу сертификата в качестве аргумента и возвращает количество дней до истечения срока действия сертификата. Если количество дней до истечения срока действия сертификата больше или равно 0, значение метрики обновляется с помощью функции Set() :

     for {
            apacheDaysUntilExpiry := checkCertExpiry("/etc/pki/ovirt-engine/certs/apache.cer")
            if apacheDaysUntilExpiry >= 0 {
                apacheCertExpiry.Set(float64(apacheDaysUntilExpiry))
            }
            wsProxyDaysUntilExpiry := checkCertExpiry("/etc/pki/ovirt-engine/certs/websocket-proxy.cer")
            if wsProxyDaysUntilExpiry >= 0 {
                wsProxyCertExpiry.Set(float64(wsProxyDaysUntilExpiry))
            }
            time.Sleep(1 * time.Hour)
        }
    }

    Если срок действия сертификата не удалось определить, тогда возвращается -1:

    func checkCertExpiry(certFile string) int {
        log.Printf("Checking certificate %s\n", certFile)
        file, err := os.Open(certFile)
        if err != nil {
            log.Printf("Failed to open certificate %s: %v", certFile, err)
            return -1
        }
        defer file.Close()
        certData, err := io.ReadAll(file)
        if err != nil {
            log.Printf("Failed to read certificate %s: %v", certFile, err)
            return -1
        }
        block, _ := pem.Decode(certData)
        if block == nil {
            log.Printf("Failed to decode PEM block for %s", certFile)
            return -1
        }
        cert, err := x509.ParseCertificate(block.Bytes)
        if err != nil {
            log.Printf("Failed to parse certificate %s: %v", certFile, err)
            return -1
        }
        daysUntilExpiry := int(cert.NotAfter.Sub(time.Now()).Hours() / 24)
        log.Printf("Certificate %s expires in %d days\n", certFile, daysUntilExpiry)
        return daysUntilExpiry
    }

    В функции checkCertExpiry() сначала открывается файл сертификата с помощью функции os.Open(). Потом данные сертификата читаются из файла с помощью функции io.ReadAll(). Далее данные сертификата декодируются из формата PEM с помощью функции `pem.Decode(). Затем данные сертификата парсятся в структуру x509.Certificate с помощью функции x509.ParseCertificate().

    После этого вычисляется количество дней до истечения срока действия сертификата путем вычитания текущего времени из времени истечения срока действия сертификата с помощью функции Sub() и преобразования результата в дни. Количество дней до истечения срока действия сертификата возвращается функцией checkCertExpiry().

    Итог

    В ходе реализации мониторинга SSL/TLS-сертификатов в экосистеме oVirt мы создали надёжное и автоматизированное решение на основе самописного экспортера cert_checker. Этот инструмент позволяет в режиме реального времени отслеживать сроки истечения ключевых сертификатов — apache.cer и websocket-proxy.cer, — предотвращая потенциальные простои в работе веб-интерфейса и консольных подключений к виртуальным машинам.

    Интеграция с Prometheus и Grafana обеспечила нам централизованное наблюдение, а настройка алертинга позволила оперативно реагировать на приближающееся окончание срока действия сертификатов — за 14 дней до истечения, а не в последний момент.

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

    С учетом нескольких месяцев эксплуатации, пока «причесывалась» эта статья, можно констатировать следующее: решение оказалось простым, но эффективным: благодаря использованию стандартных библиотек Go и экосистемы Prometheus, мы получили гибкий и легко поддерживаемый компонент, который можно быстро адаптировать под другие типы сертификатов или системы. Важно, что теперь мониторинг стал проактивным — вместо реагирования на инциденты мы можем предотвращать их заранее.

    А как вы организуете мониторинг сертификатов в своей инфраструктуре?

    Серверы для мониторинга
    Закажите сервер с предустановленным ПО для мониторинга: Grafana, Zabbix, Prometheus и другими.

    Другие статьи

    05.09.2025

    Обзор NetFlow-коллектора с визуализацией Akvorado: от развертывания до практического использования

    Мы проведем вас через все этапы работы с инструментом Akvorado для сбора и визуализации сетевого трафика. От знакомства с архитектурой до тонкостей развертывания — мы опираемся на наш собственный опыт, чтобы сделать процесс максимально понятным и эффективным.

    02.09.2025

    Хватит ли мне недорогой VPS? Сравнение VPS по производительности

    Стоит ли экономить на VPS или лучше взять тариф с запасом? Мы протестировали четыре недорогих конфигурации HOSTKEY и наглядно показали, для каких задач хватит минимального тарифа, а где разумнее сразу инвестировать в более мощный сервер.

    31.08.2025

    Foreman в изоляции: как мы построили отказоустойчивую и безопасную систему для массового деплоя ОС

    Делимся опытом трансформации нашей инфраструктуры: от децентрализованных экземпляров Foreman с публичными IP до защищённой, изолированной архитектуры с централизованным управлением через GitLab, повышенной безопасностью и легкой масштабируемостью.

    27.08.2025

    WordPress - путь от простой блог-платформы до лидирующей экосистемы на рынке CMS

    Как блог-платформа превратилась в главную систему управления контентом мира? История WordPress — это не просто перечисление его преимуществ, а рассказ о последовательности смелых решений, которые сделали его ключевой CMS.

    27.08.2025

    RTX PRO 6000 Blackwell Server Edition — как NVIDIA запутала всех с новым поколением своих профессиональных GPU

    NVIDIA выпустила сразу три версии RTX 6000 Blackwell — и именно Server Edition оказалась самой загадочной. Мы протестировали её в задачах LLM и генерации видео и сравнили с RTX 5090, A5000 и H100. Результаты вас удивят.

    Upload