====== 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}}