Inhaltsverzeichnis
Verifica revoca
Complessità: Bassa
Durata: 30 minuti per il setup
Obiettivo: Garantire disponibilità CRL/OCSP
Sorveglianza delle informazioni di revoca (CRL e OCSP) per una PKI funzionante.
Architettura
flowchart LR
subgraph CHECK["🔍 VERIFICA"]
C1[Download CRL]
C2[Parsing CRL]
C3[Richiesta OCSP]
end
subgraph VALIDATE["✅ VALIDAZIONE"]
V1[Firma OK?]
V2[Non scaduta?]
V3[Raggiungibile?]
end
subgraph ALERT["🚨 ALERT"]
A1[CRL scaduta]
A2[Timeout OCSP]
A3[CDP non raggiungibile]
end
C1 --> V1 & V2
C3 --> V3
V1 -->|No| A1
V2 -->|No| A1
V3 -->|No| A2
style A1 fill:#ffebee
style A2 fill:#ffebee
Monitoraggio CRL
Verificare stato 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 # Avviso se < 3 giorni al prossimo aggiornamento CRIT_HOURS=24 # Critico se < 1 giorno al prossimo aggiornamento for url in "${CRL_URLS[@]}"; do echo "Verifica: $url" # Scaricare CRL crl_data=$(curl -sf --max-time 10 "$url") if [ $? -ne 0 ]; then echo "ERRORE: CRL non raggiungibile - $url" continue fi # Parsing CRL (DER o 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 # Estrarre Next Update 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 )) # CRL Number crl_number=$(echo "$crl_info" | grep -A1 "CRL Number" | tail -1 | tr -d ' ') # Output stato if [ "$hours_left" -lt 0 ]; then echo "CRITICO: CRL scaduta! - $url" elif [ "$hours_left" -lt "$CRIT_HOURS" ]; then echo "CRITICO: CRL scade tra $hours_left ore - $url" elif [ "$hours_left" -lt "$WARN_HOURS" ]; then echo "AVVISO: CRL scade tra $hours_left ore - $url" else echo "OK: CRL valida per $hours_left ore - $url (CRL#: $crl_number)" fi # Numero certificati revocati revoked_count=$(echo "$crl_info" | grep -c "Serial Number:") echo " Revocati: $revoked_count certificati" echo "" done
Prometheus Exporter per CRL
#!/bin/bash # crl-exporter.sh - Genera metriche Prometheus 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
Alert Rule:
- alert: CRLExpiringSoon expr: crl_next_update_timestamp - time() < 86400 labels: severity: critical annotations: summary: "CRL {{ $labels.name }} scade tra < 24h" - alert: CRLUnreachable expr: crl_reachable == 0 for: 5m labels: severity: critical annotations: summary: "CRL {{ $labels.name }} non raggiungibile"
Monitoraggio OCSP
Verificare OCSP Responder
#!/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 "OCSP Responder Check: $OCSP_URL" # Inviare richiesta OCSP 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) # Calcolare tempo di risposta (ms) response_time=$(( (end_time - start_time) / 1000000 )) # Estrarre stato if echo "$response" | grep -q "good"; then status="good" elif echo "$response" | grep -q "revoked"; then status="revoked" else status="error" fi # Output echo "Stato: $status" echo "Tempo risposta: ${response_time}ms" if [ "$status" = "error" ]; then echo "ERRORE: OCSP Responder non funzionante" exit 1 fi if [ "$response_time" -gt 2000 ]; then echo "AVVISO: Tempo risposta OCSP > 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
Alert Rules:
- alert: OCSPResponderDown expr: ocsp_up == 0 for: 2m labels: severity: critical annotations: summary: "OCSP Responder {{ $labels.name }} non raggiungibile" - alert: OCSPResponseSlow expr: ocsp_response_time_ms > 2000 for: 5m labels: severity: warning annotations: summary: "OCSP {{ $labels.name }} lento: {{ $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" ) # Verificare CRL Write-Host "=== Verifica CRL ===" -ForegroundColor Cyan try { $crlResponse = Invoke-WebRequest -Uri $CrlUrl -TimeoutSec 10 Write-Host "CRL raggiungibile: OK ($($crlResponse.StatusCode))" -ForegroundColor Green # Parsing CRL (richiede strumenti aggiuntivi o .NET) $crlBytes = $crlResponse.Content # ... CRL-Parsing qui } catch { Write-Host "ERRORE CRL: $_" -ForegroundColor Red } # Verificare OCSP (semplificato via openssl) Write-Host "`n=== Verifica 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 "Stato OCSP: GOOD" -ForegroundColor Green } elseif ($ocspResult -match "revoked") { Write-Host "Stato OCSP: REVOKED" -ForegroundColor Yellow } else { Write-Host "Stato OCSP: ERROR" -ForegroundColor Red } } catch { Write-Host "ERRORE OCSP: $_" -ForegroundColor Red }
Checklist
| # | Punto di verifica | ✓ |
| — | ——————- | — |
| 1 | URL CRL definiti | ☐ |
| 2 | Download CRL funzionante | ☐ |
| 3 | Avviso scadenza CRL configurato | ☐ |
| 4 | URL OCSP definito | ☐ |
| 5 | Risposta OCSP funzionante | ☐ |
| 6 | Prometheus Exporter attivo | ☐ |
| 7 | Alert configurati | ☐ |
Documentazione correlata
- Revocare certificato – Aggiornare CRL
- Monitoraggio scadenze – Scadenza certificati
- Scenari revoca – Guide dettagliate
« ← Monitoraggio scadenze | → Audit logging »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: il 30/01/2026 alle 01:44