Настройка мониторинга SSL-сертификатов (срок истечения)
Просроченный SSL-сертификат делает сайт недоступным для всех пользователей. Браузеры показывают страницу с предупреждением, SEO-позиции падают, доверие пользователей потеряно. Мониторинг срока истечения — одна из самых простых задач с высоким влиянием на доступность.
Что отслеживать
- Срок истечения основного домена
- Сертификаты поддоменов (каждый отдельно — wildcard
*.example.comне всегда используется) - Промежуточные сертификаты в цепочке (CA chain)
- Сертификаты внутренних сервисов (API, внутренние домены)
Prometheus Blackbox Exporter
# blackbox.yml
modules:
https_check:
prober: http
timeout: 15s
http:
valid_status_codes: [] # Любой статус — проверяем только SSL
method: HEAD
tls_config:
insecure_skip_verify: false
fail_if_ssl: false
fail_if_not_ssl: true
# prometheus.yml scrape config
scrape_configs:
- job_name: 'ssl_certificate_check'
metrics_path: /probe
params:
module: [https_check]
static_configs:
- targets:
- https://example.com
- https://api.example.com
- https://admin.example.com
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
Метрика probe_ssl_earliest_cert_expiry содержит timestamp истечения сертификата.
Алерт в Prometheus:
- alert: SSLCertificateExpiringSoon
expr: probe_ssl_earliest_cert_expiry - time() < 30 * 24 * 3600
labels:
severity: warning
annotations:
summary: "SSL cert on {{ $labels.instance }} expires in {{ $value | humanizeDuration }}"
- alert: SSLCertificateExpiryCritical
expr: probe_ssl_earliest_cert_expiry - time() < 7 * 24 * 3600
labels:
severity: critical
annotations:
summary: "SSL cert on {{ $labels.instance }} expires in {{ $value | humanizeDuration }}!"
Python скрипт для мониторинга
import ssl
import socket
from datetime import datetime, timezone
def check_ssl_expiry(hostname: str, port: int = 443) -> dict:
context = ssl.create_default_context()
with socket.create_connection((hostname, port), timeout=10) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
expiry_str = cert['notAfter']
expiry_date = datetime.strptime(expiry_str, '%b %d %H:%M:%S %Y %Z')
expiry_date = expiry_date.replace(tzinfo=timezone.utc)
days_remaining = (expiry_date - datetime.now(timezone.utc)).days
return {
'hostname': hostname,
'expires_at': expiry_date.isoformat(),
'days_remaining': days_remaining,
'issuer': dict(x[0] for x in cert['issuer']),
'subject': dict(x[0] for x in cert['subject'])
}
Автоматическое продление с Let's Encrypt
Если использовать Let's Encrypt + Certbot или ACME-клиент, ручное продление не нужно. Но мониторинг всё равно необходим — автоматика иногда ломается.
# Проверить статус certbot таймера
systemctl status certbot.timer
# Тестовый прогон без реального обновления
certbot renew --dry-run
Certbot обновляет сертификаты при остатке < 30 дней. Мониторинг срабатывает при < 30 дней = автоматика не сработала вовремя.
Упtime Robot / Better Uptime
Самый быстрый вариант — внешние сервисы мониторинга SSL:
- Uptime Robot (бесплатный план): проверка SSL expiry, уведомление за 30/7/1 день
- Better Uptime, StatusCake: аналогично
Настройка: 5 минут. Подходит как дополнение к Prometheus-мониторингу.
Мониторинг в AWS Certificate Manager
Для сертификатов, управляемых через ACM:
resource "aws_cloudwatch_metric_alarm" "acm_cert_expiry" {
alarm_name = "acm-cert-expiry"
comparison_operator = "LessThanThreshold"
evaluation_periods = 1
metric_name = "DaysToExpiry"
namespace = "AWS/CertificateManager"
period = 86400 # раз в сутки
statistic = "Minimum"
threshold = 30
dimensions = {
CertificateArn = aws_acm_certificate.main.arn
}
alarm_actions = [aws_sns_topic.alerts.arn]
}
Сроки настройки
- Blackbox Exporter + Prometheus алерты — 0.5-1 день
- Python скрипт + scheduled lambda/cron — 0.5 дня
- Внешний сервис (Uptime Robot) — 30 минут







