====== Preverjanje preklica ======
**Kompleksnost:** Nizka \\
**Trajanje:** 30 minut nastavitve \\
**Cilj:** Zagotoviti razpoložljivost CRL/OCSP
Spremljanje informacij o preklicu (CRL in OCSP) za delujoč PKI.
----
===== Arhitektura =====
flowchart LR
subgraph CHECK["PREVERJANJE"]
C1[Prenos CRL]
C2[Razčlenjevanje CRL]
C3[OCSP zahteva]
end
subgraph VALIDATE["VALIDACIJA"]
V1[Podpis OK?]
V2[Ni potekel?]
V3[Dosegljiv?]
end
subgraph ALERT["OPOZORILO"]
A1[CRL potekel]
A2[OCSP časovna omejitev]
A3[CDP ni dosegljiv]
end
C1 --> V1 & V2
C3 --> V3
V1 -->|Ne| A1
V2 -->|Ne| A1
V3 -->|Ne| A2
style A1 fill:#ffebee
style A2 fill:#ffebee
----
===== Nadzor CRL =====
==== Preverjanje statusa CRL ====
#!/bin/bash
# /usr/local/bin/check-crl.sh
CRL_URLS=(
"http://crl.example.com/intermediate.crl"
"http://crl.example.com/root.crl"
)
WARN_HOURS=72 # Opozorilo ko < 3 dni do naslednje posodobitve
CRIT_HOURS=24 # Kritično ko < 1 dan do naslednje posodobitve
for url in "${CRL_URLS[@]}"; do
echo "Preverjam: $url"
# Prenos CRL
crl_data=$(curl -sf --max-time 10 "$url")
if [ $? -ne 0 ]; then
echo "NAPAKA: CRL ni dosegljiv - $url"
continue
fi
# Razčlenjevanje CRL (DER ali PEM)
if [[ "$crl_data" == *"-----BEGIN"* ]]; then
crl_info=$(echo "$crl_data" | openssl crl -text -noout)
else
crl_info=$(echo "$crl_data" | openssl crl -inform DER -text -noout)
fi
# Ekstrakcija naslednje posodobitve
next_update=$(echo "$crl_info" | grep "Next Update" | sed 's/.*: //')
next_epoch=$(date -d "$next_update" +%s)
now_epoch=$(date +%s)
hours_left=$(( (next_epoch - now_epoch) / 3600 ))
# Številka CRL
crl_number=$(echo "$crl_info" | grep -A1 "CRL Number" | tail -1 | tr -d ' ')
# Izpis statusa
if [ "$hours_left" -lt 0 ]; then
echo "KRITIČNO: CRL je potekel! - $url"
elif [ "$hours_left" -lt "$CRIT_HOURS" ]; then
echo "KRITIČNO: CRL poteče čez $hours_left ur - $url"
elif [ "$hours_left" -lt "$WARN_HOURS" ]; then
echo "OPOZORILO: CRL poteče čez $hours_left ur - $url"
else
echo "OK: CRL veljaven še $hours_left ur - $url (CRL#: $crl_number)"
fi
# Število preklicanih certifikatov
revoked_count=$(echo "$crl_info" | grep -c "Serial Number:")
echo " Preklicani: $revoked_count certifikatov"
echo ""
done
==== Prometheus Exporter za CRL ====
#!/bin/bash
# crl-exporter.sh - Generira Prometheus metrike
METRICS_FILE="/var/lib/node_exporter/textfile_collector/crl.prom"
cat /dev/null > "$METRICS_FILE"
CRL_URLS=(
"intermediate|http://crl.example.com/intermediate.crl"
"root|http://crl.example.com/root.crl"
)
for entry in "${CRL_URLS[@]}"; do
IFS='|' read -r name url <<< "$entry"
crl_data=$(curl -sf --max-time 10 "$url" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "crl_reachable{name=\"$name\"} 0" >> "$METRICS_FILE"
continue
fi
echo "crl_reachable{name=\"$name\"} 1" >> "$METRICS_FILE"
next_update=$(echo "$crl_data" | openssl crl -inform DER -nextupdate -noout 2>/dev/null | cut -d= -f2)
if [ -n "$next_update" ]; then
next_epoch=$(date -d "$next_update" +%s)
echo "crl_next_update_timestamp{name=\"$name\"} $next_epoch" >> "$METRICS_FILE"
fi
revoked=$(echo "$crl_data" | openssl crl -inform DER -text -noout 2>/dev/null | grep -c "Serial Number:")
echo "crl_revoked_count{name=\"$name\"} $revoked" >> "$METRICS_FILE"
done
**Pravilo opozorila:**
- alert: CRLExpiringSoon
expr: crl_next_update_timestamp - time() < 86400
labels:
severity: critical
annotations:
summary: "CRL {{ $labels.name }} poteče v < 24h"
- alert: CRLUnreachable
expr: crl_reachable == 0
for: 5m
labels:
severity: critical
annotations:
summary: "CRL {{ $labels.name }} ni dosegljiv"
----
===== Nadzor OCSP =====
==== Preverjanje OCSP odzivnika ====
#!/bin/bash
# /usr/local/bin/check-ocsp.sh
OCSP_URL="http://ocsp.example.com"
ISSUER_CERT="/etc/pki/CA/intermediate-ca.pem"
TEST_CERT="/etc/ssl/certs/test-server.pem"
echo "Preverjanje OCSP odzivnika: $OCSP_URL"
# Pošiljanje OCSP zahteve
start_time=$(date +%s%N)
response=$(openssl ocsp \
-issuer "$ISSUER_CERT" \
-cert "$TEST_CERT" \
-url "$OCSP_URL" \
-resp_text 2>&1)
end_time=$(date +%s%N)
# Izračun odzivnega časa (ms)
response_time=$(( (end_time - start_time) / 1000000 ))
# Ekstrakcija statusa
if echo "$response" | grep -q "good"; then
status="good"
elif echo "$response" | grep -q "revoked"; then
status="revoked"
else
status="error"
fi
# Izpis
echo "Status: $status"
echo "Odzivni čas: ${response_time}ms"
if [ "$status" = "error" ]; then
echo "NAPAKA: OCSP odzivnik ne deluje"
exit 1
fi
if [ "$response_time" -gt 2000 ]; then
echo "OPOZORILO: OCSP odzivni čas > 2s"
fi
==== OCSP Prometheus Exporter ====
#!/bin/bash
# ocsp-exporter.sh
METRICS_FILE="/var/lib/node_exporter/textfile_collector/ocsp.prom"
OCSP_ENDPOINTS=(
"intermediate|http://ocsp.example.com|/etc/pki/CA/intermediate.pem|/etc/ssl/certs/test.pem"
)
cat /dev/null > "$METRICS_FILE"
for entry in "${OCSP_ENDPOINTS[@]}"; do
IFS='|' read -r name url issuer cert <<< "$entry"
start_time=$(date +%s%N)
response=$(openssl ocsp -issuer "$issuer" -cert "$cert" -url "$url" -resp_text 2>&1)
exit_code=$?
end_time=$(date +%s%N)
response_time=$(( (end_time - start_time) / 1000000 ))
echo "ocsp_response_time_ms{name=\"$name\"} $response_time" >> "$METRICS_FILE"
if [ $exit_code -eq 0 ]; then
echo "ocsp_up{name=\"$name\"} 1" >> "$METRICS_FILE"
else
echo "ocsp_up{name=\"$name\"} 0" >> "$METRICS_FILE"
fi
if echo "$response" | grep -q "good"; then
echo "ocsp_status{name=\"$name\"} 0" >> "$METRICS_FILE" # 0=good
elif echo "$response" | grep -q "revoked"; then
echo "ocsp_status{name=\"$name\"} 1" >> "$METRICS_FILE" # 1=revoked
else
echo "ocsp_status{name=\"$name\"} 2" >> "$METRICS_FILE" # 2=unknown/error
fi
done
**Pravila opozoril:**
- alert: OCSPResponderDown
expr: ocsp_up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "OCSP odzivnik {{ $labels.name }} ni dosegljiv"
- alert: OCSPResponseSlow
expr: ocsp_response_time_ms > 2000
for: 5m
labels:
severity: warning
annotations:
summary: "OCSP {{ $labels.name }} počasen: {{ $value }}ms"
----
===== Blackbox Exporter =====
# blackbox.yml
modules:
tls_connect:
prober: tcp
timeout: 5s
tcp:
tls: true
tls_config:
insecure_skip_verify: false
http_crl:
prober: http
timeout: 10s
http:
method: GET
valid_status_codes: [200]
fail_if_body_not_matches_regexp: ["-----BEGIN X509 CRL-----|^\x30"]
ocsp_check:
prober: http
timeout: 5s
http:
method: POST
headers:
Content-Type: application/ocsp-request
----
===== PowerShell (Windows) =====
# Check-Revocation.ps1
param(
[string]$OcspUrl = "http://ocsp.example.com",
[string]$CrlUrl = "http://crl.example.com/intermediate.crl"
)
# Preverjanje CRL
Write-Host "=== Preverjanje CRL ===" -ForegroundColor Cyan
try {
$crlResponse = Invoke-WebRequest -Uri $CrlUrl -TimeoutSec 10
Write-Host "CRL dosegljiv: OK ($($crlResponse.StatusCode))" -ForegroundColor Green
# Razčlenjevanje CRL (zahteva dodatna orodja ali .NET)
$crlBytes = $crlResponse.Content
# ... razčlenjevanje CRL tukaj
}
catch {
Write-Host "CRL NAPAKA: $_" -ForegroundColor Red
}
# Preverjanje OCSP (poenostavljeno preko openssl)
Write-Host "`n=== Preverjanje OCSP ===" -ForegroundColor Cyan
try {
$certPath = "C:\certs\test.pem"
$issuerPath = "C:\certs\intermediate.pem"
$ocspResult = & openssl ocsp -issuer $issuerPath -cert $certPath -url $OcspUrl -text 2>&1
if ($ocspResult -match "good") {
Write-Host "OCSP status: GOOD" -ForegroundColor Green
}
elseif ($ocspResult -match "revoked") {
Write-Host "OCSP status: REVOKED" -ForegroundColor Yellow
}
else {
Write-Host "OCSP status: ERROR" -ForegroundColor Red
}
}
catch {
Write-Host "OCSP NAPAKA: $_" -ForegroundColor Red
}
----
===== Kontrolni seznam =====
| # | Kontrolna točka | |
|---|-----------------|---|
| 1 | URL-ji CRL definirani | |
| 2 | Prenos CRL deluje | |
| 3 | Opozorilo o izteku CRL konfigurirano | |
| 4 | URL OCSP definiran | |
| 5 | OCSP odziv deluje | |
| 6 | Prometheus Exporter aktiven | |
| 7 | Opozorila konfigurirana | |
----
===== Povezana dokumentacija =====
* [[..:tagesgeschaeft:zertifikat-widerrufen|Preklic certifikata]] – Posodobitev CRL
* [[.:ablauf-monitoring|Nadzor izteka]] – Itek certifikatov
* [[sl:int:pqcrypt:szenarien:widerruf:start|Scenariji preklica]] – Podrobna navodila
----
<< [[.:ablauf-monitoring|← Nadzor izteka]] | [[.:audit-logging|→ Revizijsko beleženje]] >>
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//
{{tag>monitoring crl ocsp revocation operator}}