Будь всегда в курсе: мониторим сертификаты с помощью Prometheus и Telegram

—

от автора

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

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

Глубже в технику: Grafana, Prometheus и наши экспортеры

Сначала запустим Grafana и Prometheus — это наши главные инструменты для мониторинга. Затем поболтаем об экспортерах и подключим один из них, добавим крутую панельку с графиками. Чтобы всё это дело не пропустить, научим Alertmanager слать нам уведомления в Telegram.

1. Начнем с основ: Grafana + Prometheus и Docker Compose

Для тех, кто в теме и уже тысячу раз слышал о awesome-compose/prometheus-grafana, шаг можно пропустить. Для остальных — вам понадобится compose.yml файл:

services:   prometheus:     image: prom/prometheus     container_name: prometheus     command:       - "--config.file=/etc/prometheus/prometheus_config.yml"     ports:       - 9090:9090     restart: unless-stopped     volumes:       - ./prometheus:/etc/prometheus       - prom_data:/prometheus   grafana:     image: grafana/grafana     container_name: grafana     ports:       - 3000:3000     restart: unless-stopped     env_file: .env     environment:       - GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}       - GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}     volumes:       - ./grafana:/etc/grafana/provisioning/datasources volumes:   prom_data:

Теперь создайте директорию prometheus с файлом prometheus_config.yml:

global:   scrape_interval: 15s   scrape_timeout: 10s   evaluation_interval: 15s

И то же самое для директории grafana и файла datasource.yml:

apiVersion: 1  datasources:   - name: Prometheus     type: prometheus     url: http://prometheus:9090     isDefault: true     access: proxy     editable: true

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

Создайте файл .env и добавьте ИМЯ_ПОЛЬЗОВАТЕЛЯ_GRAFANA и ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_GRAFANA:

GF_SECURITY_ADMIN_USER=<ИМЯ_ПОЛЬЗОВАТЕЛЯ_GRAFANA> GF_SECURITY_ADMIN_PASSWORD=<ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ_GRAFANA>

Поднимаем всю эту красоту:

docker-compose up -d

Так, магия Docker сработала, и у нас есть Grafana на порту 3000 и Prometheus на 9090. Просто? Просто!

2. Погружаемся в мир экспортеров: выбор инструмента

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

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

3. Работа с ssl_exporter

Мы уже обсудили, что представляет собой ssl_exporter. Следит за сертификатами хорошо
и по-разному. Давайте добавим его в compose.yml:

ssl_exporter:   image: ribbybibby/ssl-exporter   ports:     - "9219:9219"

Сегодня нашей целью будет prometheus.io. Добавляем scrape_configs в prometheus_config.yml:

scrape_configs:   - job_name: "ssl-exporter"     metrics_path: /probe     static_configs:       - targets:           - prometheus.io:443     relabel_configs:       - source_labels: [__address__]         target_label: __param_target       - source_labels: [__param_target]         target_label: instance       - target_label: __address__         replacement: ssl_exporter:9219

Так, перезапускаем наш compose.yml:

docker-compose restart

В Prometheus выполняем PromQL запрос – ssl_probe_success и если мы видим следующее, то значит настроили все верно:

ssl_probe_success{instance="prometheus.io:443", job="ssl-exporter"}

По умолчанию экспортер создает TCP-соединение с целью. В большинстве случаев этого хватает, но если вы хотите использовать проксирование через http, используйте модуль https. Кроме того, можно с помощью file следить за сертификатами на диске:

scrape_configs:   - job_name: "ssl-files"     metrics_path: /probe     params:       module: ["file"]       target: ["/etc/ssl/cert.pem"]     kubernetes_sd_configs:       - role: node     relabel_configs:       - source_labels: [__address__]         regex: ^(.*):(.*)$         target_label: __address__         replacement: ${1}:9219

Если сертификатов несколько, можно использовать глоб-поиск, что позволяет захватить сразу несколько файлов:

scrape_configs:   - job_name: "ssl-files"     metrics_path: /probe     params:       module: ["file"]       target: ["/etc/ssl/**/*.pem"]     kubernetes_sd_configs:       - role: node     relabel_configs:       - source_labels: [__address__]         regex: ^(.*):(.*)$         target_label: __address__         replacement: ${1}:9219

Также можно использовать в связке с Kubernetes, в документации больше информации.

4. Добавляем панель в Grafana

Велосипед изобретать не будем, а просто авторизовываемся и импортируем готовую панель из репозитория ssl_exporter:

В панели SSL Certificates отображается таблица с данными о каждом сертификате: его имя, инстанс, имя эмитента, выдавшего сертификат, серийный номер и время жизни. Экспортер имеет обширный набор метрик, позволяющих настроить панель под любые потребности.

В панели SSL Certificates отображается таблица с данными о каждом сертификате: его имя, инстанс, имя эмитента, выдавшего сертификат, серийный номер и время жизни. Экспортер имеет обширный набор метрик, позволяющих настроить панель под любые потребности.

Как не проспать проблемы

Что у нас в планах? Поднимем невероятно простой, но очень полезный сервис на Flask’е, который будет ловить уведомления от Alertmanager и пересылать их в Telegram. Создадим бот и настроим Alertmanager на отправку уведомлений.

1. Взлетаем с Flask

Ладно, не будем мелочиться, заводим директорию telegram и кидаем туда файлик app.py с элегантным, минималистичным и в стиле true pythonista кодом:

import os import requests  from flask import Flask, request, jsonify  app = Flask(__name__)  TELEGRAM_TOKEN = os.environ["TELEGRAM_TOKEN"] CHAT_ID = os.environ["TELEGRAM_CHAT_ID"] TELEGRAM_URL = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"   @app.route("/alert", methods=["POST"]) def webhook():     data = request.json     alertname = data["alerts"][0]["labels"]["alertname"]     instance = data["alerts"][0]["labels"]["instance"]     summary = data["alerts"][0]["annotations"]["summary"]     text = f"⚠️ Alarm! {alertname} for {instance}. \n{summary}"     payload = {"chat_id": CHAT_ID, "text": text}     response = requests.post(TELEGRAM_URL, data=payload)     return jsonify(status="success"), 200   if __name__ == "__main__":     app.run(host="0.0.0.0", port=8000)

А еще пригодится Dockerfile:

FROM python:3.10-alpine WORKDIR /app COPY . /app RUN pip3 install -r requirements.txt ENTRYPOINT ["python3"] CMD ["app.py"]

Ну и, разумеется, незаменимый requirements.txt:

flask requests

2. Крафтим бота:

  1. Запустим @BotFather в Telegram.

  2. /newbot, даем ему имя и вуаля! У вас в руках: ТОКЕН_БОТА.

  3. Выясним свой chat_id, отправив /start своему боту и заглянув на https://api.telegram.org/bot<ТОКЕН_БОТА>/getUpdates. Найдите result[0]message.chat.id и запомните, это будет ваш ВАШ_ЧАТ_ID.

Теперь добавьте всё это в compose.yml:

telegram:   build:     context: telegram   stop_signal: SIGINT   env_file: .env   environment:     - TELEGRAM_TOKEN=${TELEGRAM_TOKEN}     - TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}   ports:     - "8000:8000"

А секреты ТОКЕН_БОТА и ВАШ_ЧАТ_ID в .env :

TELEGRAM_TOKEN=<ТОКЕН_БОТА> TELEGRAM_CHAT_ID=<ВАШ_ЧАТ_ID>

3. Дружим Alertmanager с Telegram

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

Начнем с малого. Напишем правило, которое даст нам знать, когда у сертификата останется менее 90 дней жизни. Для желающих углубиться — в документации собраны разные запросы. В prometheus создаем файл alert.rules.yml и пишем туда:

groups:   - name: ssl-alerts     rules:       - alert: Expiry Soon         expr: ssl_cert_not_after - time() < 86400 * 90         for: 1m         labels:           severity: critical         annotations:           summary: "SSL certificate is expiring soon (less than 90 days)"

Допишем пару строк в prometheus_config.yml:

rule_files:   - "/etc/prometheus/alert.rules.yml" alerting:   alertmanagers:     - static_configs:         - targets:             - "alertmanager:9093"

Теперь давайте сделаем следующее: создадим директорию под названием alertmanager и положим в нее файл alertmanager_config.yml:

route:   group_by: ["instance"]   repeat_interval: 3h   receiver: "telegram-webhook"  receivers:   - name: "telegram-webhook"     webhook_configs:       - url: "http://telegram:8000/alert"

Что ж, наш compose.yml тоже хочет внимания, добавляем контейнер alertmanager:

alertmanager:   image: quay.io/prometheus/alertmanager   container_name: alertmanager   command:     - "--config.file=/etc/alertmanager/alertmanager_config.yml"   ports:     - "9093:9093"   volumes:     - ./alertmanager:/etc/alertmanager

А теперь — магия:

docker-compose down; docker-compose up -d

Итак, смотрим, что наш Alertmanager чувствует себя комфортно:

и правило в Prometheus заняло свою рабочую позицию:

Примерно через минуту Prometheus поймет, что есть какие-то проблемы:

И еще примерно через 30 секунд Alertmanager отправит уведомление в наш сервис:

Который перешлет его к вам в Telegram:

Вот и всё! Теперь у вас в арсенале есть бот, который держит руку на пульсе ваших сервисов и, в случае чего, моментально бьет тревогу! Ну что, вы ведь тоже чувствуете этот аромат возможностей?

Заключение

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


ссылка на оригинал статьи https://habr.com/ru/articles/763390/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *