====== Nadzor izteka ======
**Kompleksnost:** Nizka-Srednja \\
**Trajanje:** 1-2 uri nastavitve \\
**Cilj:** Nobeden certifikat ne sme poteči neopaženo
Spremljanje datumov izteka certifikatov z različnimi orodji in strategijami opozarjanja.
----
===== Arhitektura =====
flowchart LR
subgraph SOURCES["VIRI"]
F[Datotečni sistem]
K[Kubernetes Secrets]
R[Oddaljeni TLS]
S[Shrambe certifikatov]
end
subgraph COLLECTOR["ZBIRALNIK"]
E[cert-exporter]
N[node_exporter]
B[blackbox_exporter]
end
subgraph STORAGE["PROMETHEUS"]
P[(Prometheus)]
end
subgraph ALERT["OPOZORILO"]
A[Alertmanager]
M[E-pošta/Slack/Teams]
end
F --> E --> P --> A --> M
K --> E
R --> B --> P
S --> N --> P
style A fill:#ffebee
style P fill:#e3f2fd
----
===== Možnost 1: Prometheus + cert-exporter =====
==== Namestitev ====
# Prenos cert-exporter
wget https://github.com/enix/x509-certificate-exporter/releases/download/v3.12.0/x509-certificate-exporter_3.12.0_linux_amd64.tar.gz
tar xzf x509-certificate-exporter_*.tar.gz
sudo mv x509-certificate-exporter /usr/local/bin/
# Ustvarjanje Systemd storitve
cat << 'EOF' | sudo tee /etc/systemd/system/cert-exporter.service
[Unit]
Description=X509 Certificate Exporter
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/x509-certificate-exporter \
--watch-file=/etc/ssl/certs/*.pem \
--watch-file=/etc/nginx/ssl/*.crt \
--watch-kubeconf=false
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now cert-exporter
==== Konfiguracija Prometheus ====
# /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: 'cert-exporter'
static_configs:
- targets: ['localhost:9793']
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'pki-server'
# Preverjanje oddaljenih TLS končnih točk
- job_name: 'blackbox-tls'
metrics_path: /probe
params:
module: [tls_connect]
static_configs:
- targets:
- https://api.example.com
- https://web.example.com
- https://mail.example.com:465
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
==== Pravila opozoril ====
# /etc/prometheus/rules/cert-alerts.yml
groups:
- name: certificate-alerts
rules:
- alert: CertificateExpiringSoon
expr: x509_cert_not_after - time() < 30 * 24 * 3600
for: 1h
labels:
severity: warning
annotations:
summary: "Certifikat {{ $labels.filepath }} poteče v < 30 dneh"
description: "Preostali čas: {{ $value | humanizeDuration }}"
- alert: CertificateExpireCritical
expr: x509_cert_not_after - time() < 7 * 24 * 3600
for: 10m
labels:
severity: critical
annotations:
summary: "KRITIČNO: Certifikat {{ $labels.filepath }} poteče v < 7 dneh"
description: "Datum izteka: {{ $value | humanizeTimestamp }}"
- alert: CertificateExpired
expr: x509_cert_not_after - time() < 0
for: 0m
labels:
severity: critical
annotations:
summary: "Certifikat {{ $labels.filepath }} je POTEKEL"
- alert: CAExpiringSoon
expr: x509_cert_not_after{is_ca="true"} - time() < 365 * 24 * 3600
for: 1d
labels:
severity: warning
annotations:
summary: "CA certifikat {{ $labels.subject }} poteče v < 1 letu"
----
===== Možnost 2: Grafana nadzorna plošča =====
{
"dashboard": {
"title": "Certificate Expiry Dashboard",
"panels": [
{
"title": "Iztekajoci certifikati (< 30 dni)",
"type": "table",
"targets": [
{
"expr": "sort_desc((x509_cert_not_after - time()) / 86400)",
"format": "table"
}
],
"fieldConfig": {
"overrides": [
{
"matcher": { "id": "byName", "options": "Value" },
"properties": [
{
"id": "custom.displayMode",
"value": "color-background"
},
{
"id": "thresholds",
"value": {
"steps": [
{ "color": "red", "value": 0 },
{ "color": "orange", "value": 7 },
{ "color": "yellow", "value": 30 },
{ "color": "green", "value": 90 }
]
}
}
]
}
]
}
},
{
"title": "Certifikati po casu izteka",
"type": "stat",
"targets": [
{
"expr": "count(x509_cert_not_after - time() < 7 * 86400)",
"legendFormat": "< 7 dni"
},
{
"expr": "count(x509_cert_not_after - time() < 30 * 86400)",
"legendFormat": "< 30 dni"
}
]
}
]
}
}
----
===== Možnost 3: Preprosta skripta (brez Prometheus) =====
#!/bin/bash
# /usr/local/bin/cert-check-notify.sh
WARN_DAYS=30
CRIT_DAYS=7
MAIL_TO="pki-team@example.com"
WEBHOOK_URL="https://teams.example.com/webhook/..."
check_cert() {
local cert="$1"
local days_left=$(( ($(openssl x509 -enddate -noout -in "$cert" 2>/dev/null | cut -d= -f2 | date -f - +%s) - $(date +%s)) / 86400 ))
local subject=$(openssl x509 -subject -noout -in "$cert" 2>/dev/null | sed 's/subject=//')
if [ "$days_left" -lt 0 ]; then
echo "POTEKEL|$cert|$subject|$days_left"
elif [ "$days_left" -lt "$CRIT_DAYS" ]; then
echo "KRITICNO|$cert|$subject|$days_left"
elif [ "$days_left" -lt "$WARN_DAYS" ]; then
echo "OPOZORILO|$cert|$subject|$days_left"
fi
}
# Preverjanje vseh certifikatov
results=""
for cert in /etc/ssl/certs/*.pem /etc/nginx/ssl/*.crt; do
[ -f "$cert" ] || continue
result=$(check_cert "$cert")
[ -n "$result" ] && results+="$result\n"
done
# Pošiljanje obvestila če je potrebno
if [ -n "$results" ]; then
# E-pošta
echo -e "Najdene težave s certifikati:\n\n$results" | \
mail -s "PKI opozorilo: Certifikati" "$MAIL_TO"
# Teams/Slack Webhook
curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{\"text\": \"PKI opozorilo: Certifikati\n\n$(echo -e "$results" | sed 's/|/ | /g')\"}"
fi
# Cron: Dnevno ob 08:00
echo "0 8 * * * root /usr/local/bin/cert-check-notify.sh" > /etc/cron.d/cert-check
----
===== Možnost 4: PowerShell (Windows) =====
# Check-CertificateExpiry.ps1
param(
[int]$WarnDays = 30,
[int]$CritDays = 7,
[string]$SmtpServer = "smtp.example.com",
[string]$MailTo = "pki-team@example.com"
)
$results = @()
# Lokalni certifikati
Get-ChildItem Cert:\LocalMachine\My | ForEach-Object {
$daysLeft = ($_.NotAfter - (Get-Date)).Days
$severity = if ($daysLeft -lt 0) { "POTEKEL" }
elseif ($daysLeft -lt $CritDays) { "KRITICNO" }
elseif ($daysLeft -lt $WarnDays) { "OPOZORILO" }
else { $null }
if ($severity) {
$results += [PSCustomObject]@{
Severity = $severity
Subject = $_.Subject
Thumbprint = $_.Thumbprint
DaysLeft = $daysLeft
NotAfter = $_.NotAfter
}
}
}
# Oddaljene TLS končne točke
$endpoints = @(
"api.example.com:443",
"web.example.com:443"
)
foreach ($endpoint in $endpoints) {
try {
$host, $port = $endpoint -split ':'
$cert = (New-Object System.Net.Sockets.TcpClient($host, [int]$port)).GetStream() |
ForEach-Object { (New-Object System.Net.Security.SslStream($_)).AuthenticateAsClient($host); $_.RemoteCertificate }
$daysLeft = ($cert.NotAfter - (Get-Date)).Days
# ... analogno kot zgoraj
}
catch {
$results += [PSCustomObject]@{
Severity = "NAPAKA"
Subject = $endpoint
Thumbprint = "N/A"
DaysLeft = -1
NotAfter = "Povezava neuspešna: $_"
}
}
}
# Pošiljanje poročila
if ($results.Count -gt 0) {
$body = $results | Format-Table -AutoSize | Out-String
Send-MailMessage -To $MailTo -From "pki@example.com" `
-Subject "PKI opozorilo: $($results.Count) certifikat(ov) zahteva pozornost" `
-Body $body `
-SmtpServer $SmtpServer
}
# Izhod za beleženje
$results | Format-Table
----
===== Kubernetes: cert-manager metrike =====
# ServiceMonitor za cert-manager
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: monitoring
spec:
selector:
matchLabels:
app.kubernetes.io/name: cert-manager
namespaceSelector:
matchNames:
- cert-manager
endpoints:
- port: tcp-prometheus-servicemonitor
interval: 60s
**Pomembne metrike:**
| Metrika | Opis |
|---------|------|
| ''certmanager_certificate_expiration_timestamp_seconds'' | Časovna oznaka izteka |
| ''certmanager_certificate_ready_status'' | Status pripravljenosti (1=OK) |
| ''certmanager_certificate_renewal_timestamp_seconds'' | Zadnja obnova |
----
===== Najboljše prakse =====
| Priporočilo | Utemeljitev |
|-------------|-------------|
| **30/14/7/1 dni** opozorila | Stopnjevana eskalacija |
| **CA certifikati ločeno** | Daljše opozorilo vnaprej (1 leto) |
| **Oddaljeno + lokalno** preverjanje | Različni viri napak |
| **Odstranjevanje podvojitev** | Ne 100 opozoril za 1 certifikat |
| **Povezava na navodila** v opozorilu | Neposredna navodila za ukrepanje |
----
===== Kontrolni seznam =====
| # | Kontrolna točka | |
|---|-----------------|---|
| 1 | Exporter nameščen | |
| 2 | Prometheus Scrape konfiguriran | |
| 3 | Pravila opozoril definirana | |
| 4 | Alertmanager usmerjanje | |
| 5 | Grafana nadzorna plošča | |
| 6 | Testno opozorilo poslano | |
----
===== Povezana dokumentacija =====
* [[.:alerting-setup|Nastavitev opozarjanja]] – Konfiguracija obvestil
* [[..:tagesgeschaeft:health-check|Pregled zdravja]] – Ročno preverjanje
* [[..:automatisierung:scheduled-renewal|Načrtovana obnova]] – Samodejna obnova
----
<< [[.:start|← Nadzor]] | [[.:revocation-check|→ Preverjanje preklica]] >>
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//
{{tag>monitoring prometheus grafana ablauf expiry operator}}