Налаштування моніторингу 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 днів = автоматика не спрацювала вчасно.
Uptime Robot / Better Uptime
Найшвидший варіант — зовнішні сервіси моніторингу SSL:
- Uptime Robot (безплатний план): перевірка SSL expiry, сповіщення за 30/7/1 день
- Better Uptime, StatusCake: аналогічно
Налаштування: 5 хвилин. Доповнює Prometheus-моніторинг.







